GeoDjango + PostGIS: pure geometry SRID - django

I am thinking about using django (2.0.6) with Postgres/postGIS as a backend (10/2.4?).
However, the model geometries I intend to use will not be stored "against" a spheroid (whether earth mars, etc) or any other kind of SRID. Rather a 100% pure geometry in 3D cartesian coordinates, where 1 unit = 1 meter.
How am I to declare model fields and insure they are pure geometry both:
at database level
at application level
Would this work?
geometry = models.MultiPolygonField(_('Geometry'), spatial_index=True, dim=3)
Or better to set the SRID?:
geometry = models.MultiPolygonField(_('Geometry'), spatial_index=True, dim=3, srid=0)
Many thanks

You can use SRID 3857 for 1m Cartesian grid:
models.py:
class Place(models.Model):
geom = models.PointField(srid=3857, dim=3)
def __str__(self):
return str(self.geom.coords)
However, GeoDjango does not support 3d distance calculations out of the box. For example:
from django.contrib.gis.geos import Point
from django.contrib.gis.measure import Distance
from myapp.models import Place
p = Point(100, 100, 0)
Place.objects.create(geom=p)
Place.objects.create(geom=Point(150, 100, 0))
Place.objects.create(geom=Point(100, 100, 22))
Place.objects.create(geom=Point(100, 100, 500))
Place.objects.create(geom=Point(150, 150, 0))
Place.objects.create(geom=Point(250, 250, 0))
for o in Place.objects.filter(geom__distance_lte=(p, Distance(m=100))):
print(o.geom.coords, p.distance(o.geom))
Output:
(100.0, 100.0, 0.0) 0.0
(150.0, 100.0, 0.0) 50.0
(100.0, 100.0, 22.0) 0.0
(100.0, 100.0, 500.0) 0.0
(150.0, 150.0, 0.0) 70.71067811865476
In pure PostGIS, compare ST_Distance and ST_3DDistance :
SELECT *
FROM (
SELECT
"myapp_place"."id",
ST_Distance("myapp_place"."geom",
ST_GeomFromEWKT('SRID=3857;POINT(100 100 0)')) d,
ST_AsEWKT("myapp_place"."geom")
FROM "myapp_place"
) t
WHERE d <= 100.0
vs.
SELECT *
FROM (
SELECT
"myapp_place"."id",
ST_3DDistance("myapp_place"."geom",
ST_GeomFromEWKT('SRID=3857;POINT(100 100 0)')) d,
ST_AsEWKT("myapp_place"."geom")
FROM "myapp_place"
) t
WHERE d <= 100.0

Related

PTB-OpengGL stereo rendering and eye seperation value

I tried to draw a 3D dot cloud using OpenGL asymmetric frustum parallel axis projection. The general principle can be found on this website(http://paulbourke.net/stereographics/stereorender/#). But the problem now is that when I use real eye separation(0.06m), my eyes do not fuse well. When using eye separation = 1/30 * focal length, there is no pressure. I don’t know if there is a problem with the calculation, or there is a problem with the parameters? Part of the code is posted below. Thank you all.
for view = 0:stereoViews
% Select 'view' to render (left- or right-eye):
Screen('SelectStereoDrawbuffer', win, view);
% Manually reenable 3D mode in preparation of eye draw cycle:
Screen('BeginOpenGL', win);
% Set the eye seperation:
eye = 0.06; % in meter
% Caculate the frustum shift at the near plane:
fshift = 0.5 * eye * depthrangen/(vdist/100); % vdist is the focal length, 56cm, 0.56m
right_near = depthrangen * tand(FOV/2); % depthrangen is the depth of the near plane, 0.4. %FOV is the field of view, 18°
left_near = -right_near;
top_near = right_near* aspectr;
bottom_near = -top_near;
% Setup frustum projection for this eyes 'view':
glMatrixMode(GL.PROJECTION)
glLoadIdentity;
eyeside = 1+(-2*view); % 1 for left eye, -1 for right eye
glFrustum(left_near + eyeside * fshift, right_near + eyeside * fshift, bottom_near, top_near, %depthrangen, depthrangefObj);
% Setup camera for this eyes 'view':
glMatrixMode(GL.MODELVIEW);
glLoadIdentity;
gluLookAt(0 - eyeside * 0.5 * eye, 0, 0, 0 - eyeside * 0.5 * eye, 0, -1, 0, 1, 0);
% Clear color and depths buffers:
glClear;
moglDrawDots3D(win, xyz(:,:,iframe), 10, [], [], 1);
moglDrawDots3D(win, xyzObj(:,:,iframe), 10, [], [], 1);
% Manually disable 3D mode before calling Screen('Flip')!
Screen('EndOpenGL', win);
% Repeat for other eyes view if in stereo presentation mode...
end

Artifacts when computing contours of a zoomed in texture

I have a shader that calculates contour lines based on a parameter in the program, in my case the height value of a mesh. The calculation is performed using standard derivatives as follows:
float contourWidth = 0.5;
float f = abs( fract( height ) - 0.5 );
float df = fwidth( height );
float mi = max( 0.0, contourWidth - 1.0 );
float ma = max( 1.0 , contourWidth );
float contour = clamp( (f - df * mi ) / ( df * ( ma - mi ) ), 0.0, 1.0 );
This works as expected, however when I feed the height parameter from a texture, and zoom in, such that the rendered pixels are much smaller than the sampled texels, artifacts begin to appear.
The sampled texture has linear filtering and to investigate I implemented linear filtering manually in the shader to try to isolate the problem. This resolved the issue, but I'd like to understand why this is happening and if the only solution is to manually implement linear filtering in the shader as I have, or if there is a better way.
Below is a comparison of the two rendering techniques:
I have created an working example on Shadertoy to demonstrate the issue: https://www.shadertoy.com/view/MljcDy
I'm seeing this issue on Mac OSX as well as mobile Safari (where the atrifacts are even worse)

Triangle function on angles

I need a function that works on angles (degrees for the example, but it may be radians as well) with the following (it must be continuous, I only write down some key values to understand the behavior):
any_function(angle):
0-> 0.0
45-> 0.5
90-> 1.0
135-> 0.5
180-> 0.0
225->-0.5
270->-1.0
335->-0.5
360-> 0.0
This is a simple triangular wave.
Does anything already exist in some modules or do I need to create it on my own?
For example like this (quick and dirty):
def toTriangle(angle):
if angle < 90 and angle >= 0:
t = (angle/90.)
elif angle <= 180 and angle >= 90:
t = 2-(angle/90.)
elif angle <= 270 and angle >= 180:
t = -(3-(angle/90.))
else:
t = -(4-(angle/90.))
return t
Thanks DeepSpace for your suggestion but it doesn't work out of the box:
from scipy.signal import sawtooth
sawtooth(0)
Out[4]: array(-1.0)
Here's a less quick-n-dirty solution:
def toTriangle(angle):
import math
tr = 1-4*math.fabs(0.5-math.modf(0.25+0.5*angle%(2*math.pi)/math.pi)[0] )
return t
( http://mathworld.wolfram.com/TriangleWave.html )

Pyqtgraph clip line

i'm trying to plot a smith chart in pyqtgraph. I would like to know if there is a method to clip
the ellipse items representing the imaginary circles with the real circle having radius = 1.
This is what i've done so far: i used the methods start angle e span angle of
QGraphicsEllipse, but in this way a plot also the vertical and horizontal lines of the circle.
There's a method in matplotlib called set_clip_path(), do you know if there is something like this in pyqtgraph?
import pyqtgraph as pg
plot = pg.plot()
plot.setAspectLocked()
plot.addLine(y=0)
#vector for real circle
rline = [0.2, 0.5, 1.0, 2.0, 5.0]
#vector for imaginary
xline = [0.2, 0.5, 1, 2, 5]
circle1 = pg.QtGui.QGraphicsEllipseItem(1, -1, -2, 2)
circle1.setPen(pg.mkPen(1))
plot.addItem(circle1)
for r in rline:
raggio = 1./(1+r)
circle = pg.QtGui.QGraphicsEllipseItem(1, -raggio, -raggio*2, raggio*2)
circle.setPen(pg.mkPen(0.2))
plot.addItem(circle)
for x in xline:
#printing the imaginary circle
circle = pg.QtGui.QGraphicsEllipseItem(x + 1, 0, -x*2, x*2)
circle.setPen(pg.mkPen(0.2))
circle.setStartAngle(1440)
circle.setSpanAngle(1440)
plot.addItem(circle)
EDIT
That's my final code
plot.setAspectLocked()
plot.setXRange(-1,1, padding = 0)
plot.setYRange(-1,1, padding = 0)
#plot.addLine(y=0)
rline = [0.2, 0.5, 1.0, 2.0, 5.0]
xline = [0.2, 0.5, 1, 2, 5]
circle1 = pg.QtGui.QGraphicsEllipseItem(1, -1, -2, 2)
circle1.setPen(pg.mkPen('w', width=0))
circle1.setFlag(circle1.ItemClipsChildrenToShape)
plot.addItem(circle1)
pathItem = pg.QtGui.QGraphicsPathItem()
path = pg.QtGui.QPainterPath()
path.moveTo(1, 0)
for r in rline:
raggio = 1./(1+r)
path.addEllipse(1, -raggio, -raggio*2, raggio*2)
for x in xline:
path.arcTo(x + 1, 0, -x*2, x*2, 90, -180)
path.moveTo(1, 0)
path.arcTo(x + 1, 0, -x*2, -x*2, 270, 180)
pathItem.setPath(path)
pathItem.setPen(pg.mkPen('g', width = 0.2))
pathItem.setParentItem(circle1)
`
Clipping is supported, but probably not the best option. A few possibilities:
Use QGraphicsPathItem combined with QPainterPath.arcTo to draw arcs without radial lines. This would also allow you to add multiple arcs to a single item rather than adding many items, which should improve performance.
Use Something like PlotCurveItem or arrayToQPath to manually draw your own arcs. If you use the connect argument, you'll again be able to generate multiple separate arcs on a single item.
Clipping is handled by Qt; see QGraphicsItem.itemClipsToShape and QGraphicsItem.itemClipsChildrenToShape. Beware: if you use this, you must set the pen width of the clipping object to 0 (Qt only partially supports cosmetic pens with width > 0). Example:
import pyqtgraph as pg
plot = pg.plot()
e1 = pg.QtGui.QGraphicsEllipseItem(0, 0, 4, 4)
# MUST have width=0 here, or use a non-cosmetic pen:
e1.setPen(pg.mkPen('r', width=0))
e1.setFlag(e1.ItemClipsChildrenToShape)
plot.addItem(e1)
e2 = pg.QtGui.QGraphicsEllipseItem(2, 2, 4, 4)
e2.setPen(pg.mkPen('g'))
e2.setParentItem(e1)

Plot gps-coordinates in realtime using python (fullscreen view)

I want to plot IP-addresses on a word map, I've been using Basemap with animation which does exactly what I want, except that it doesn't display the figure in fullscreen.
To make it in fullscreen I used pygame to set the worldmap (generated from Basemap) as background image and adding circles to every x/y, however, not all cities are being plotted correctly; Gothenburg and Cape Town are correct, New York is nowhere to be found and Sydney is being plotted in Cape Town.
Code for the plotting (Miller Cylindrical Projection):
{
map = Basemap(projection='mill', long_0=210)
map.drawcoastlines(color='blue')
map.drawmapboundary(fill_color='black')
map.fillcontinents(color='black',lake_color='black')
plt.savefig('map.png', bbox_inches='tight', pad_inches=0, dpi=200)
pygame.init()
bmap = pygame.image.load('map.png')
brect = bmap.get_rect()
size = (width, height) = bmap.get_size()
#Gothenburg
lat = 57.70812489
lng = 11.94975493
#Map size 620 x 454
lat = math.radians(lat)
lng = math.radians(lng)
xlat = (width / 2) + (width / (2 * math.pi + 0.4 * lat))
xlng = 1.25 * math.log(math.tan(0.25 * math.pi + 0.4 * lat))
xlng = (height / 2) - (height / (2 * 2.303412543)) * xlng
screen = pygame.display.set_mode(size)
screen.blit(bmap, brect)
pygame.draw.circle(screen, (250, 0, 0), [int(xlat), int(xlng)], 2)
pygame.display.flip()
}
I don't really know which of the two approaches which are the best one to go for. Or is there any other solution I might consider?