Creating Regions in Python - python

I am trying to use Python to create a simple solution.
I have latitude and longitude of various areas, alongside their ID number and a code. The code is used to define regions. Say three locations (near to each other) have the same code, so they form region_1 and so on. I am trying to show this on map (basically show different regions) but don't understand how to approach the problem.
I tried using Folium Choropleth but it didn't work.
I think that is because I am not looking for how a value varies across regions. I am just interested in seeing how I can use different points to represent a region on a map.
Any help to what I can look into would be appreciated!
Edit: So turns out I have to make use of Voronoi regions.
Now I tried creating those regions in Python.
Firstly I got the area shape using:
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
area = world[world.name == 'Pakistan']
area = area.to_crs(epsg=3395) # convert to World Mercator CRS
area_shape = area.iloc[0].geometry # get the Polygon
This gave the correct output. Next I had two lists, lat and long.
I combined the two lists into a 2D array and passed it to:
from geovoronoi import voronoi_regions_from_coords
region_polys, region_pts = voronoi_regions_from_coords(arr, area_shape)
This is the error I am getting now:
RuntimeError: ridge line must intersect with surrounding geometry from `geom`; this error often arises when there are points outside of the surrounding geometries; first check if all your points are inside the surrounding geometries
I googled a bit but don't know how fix the error.
The points are fine I think since I did map it in Mapinfo first.
Would appreciate any help on this!

Related

Keep lat long order using transformer.from_crs, always_xy=True not working?

I'm trying to update some code because lat/lon values are getting flipped (lat ends up in lon column and vice versa) when using Transformer.from_crs.
The line of code that is causing the issue is this, BUT only when f'epsg:{oldEPSG}'="epsg:4326" (so only when we are converting from AND to epsg:4326).
transformer = Transformer.from_crs(f'epsg:{oldEPSG}', "epsg:4326")
I have tried adding the 3rd argument always_xy=True, as suggested in https://github.com/pyproj4/pyproj/issues/510, but get the same result.
We have coordinates with epsg:6491, epsg:26919 and epsg:5646 in our database which don't have their lat/lon flipped after transforming.
I'm not really familiar with working with coordinate, so I'm confused if I need to be figuring out if they have default lat/lon or lon/lat orders (like will epsg:4326, epsg:6491, epsg:26919 and epsg:5646 all be different?).
I guess I'm just wondering why the lat/lon don't get flipped in all cases? If it's just a matter of checking whether the from and to projections are the same, I can do that. I just want to make sure I understand why this is happening in case other projections end up having the same issue.
Thank you!

Mapping density coordinates from one coordinate system to another

I'm currently trying to map a set of density coordinates onto a normalized reference. For example, say I have the following densities for 2 systems with the following reference:
System 1
|X|Y|Z|ESP|
|-|-|-|---|
|0|0|0|0.1|
|0|0|1|0.2|
|0|0|2|0.3|
|1|0|0|0.2|
|2|0|0|0.3|
System 2
|X|Y|Z|ESP|
|-|-|-|---|
|0|0|0|0.5|
|0|0|1|0.10|
|0|0|2|0.20|
|1|0|0|0.10|
|2|0|0|0.20|
|0|1|0|0.30|
|0|2|0|0.50|
Normalized Reference Map
|X|Y|Z|
|-|-|-|
|0|0|0|
|0|0|1|
|0|0|2|
|0|0|3|
|1|0|0|
|2|0|0|
|3|0|0|
|0|1|0|
|0|2|0|
|0|3|0|
I want to map the values of the independent systems onto the reference. We can assume that points that don't appear in the Systems on the reference can be the average of the surrounding ESP values. I've been trying various scipy interpolations methods like map_coordinates and interpolation, but I'm having no luck with getting everything done correctly. I was hoping to see if anyone had any thoughts here.

Python netCDF5 working with Longitude and Latitude and extracting Data

how are you doing?
I have been working on this for quite a while now, but I am not able to proceed any further.
I was given .nc Files with Cloud Based Altitudes (CBA are measurements to indicate the height of clods for a particular area).
For now I am not even able to extract Data for a single Coordinate. This Data contains the area shown in this picture, from the top left to the bottom right:
Here is a screenshot of the data I am working with:
Sorry that I can not provide more Data than that, but I don't want to get in trouble.
The cba value is the information I want to extract. So let's say I have a set of coordinates (longitude/latitude) of an area I am interested in, how would I be able to get the appropriate cba values?
I don't need a specific solution, but a direction so I can continue on my own.
For additional information this is how the .cba and .cba.values look:
I have been working with data like that before, but not this nested, so I have absolutely no idea how I can even approach that.
Is there a module/package in python which would allow me to easily handle this, so when I put in coordinates for an area it would directly give me the corresponding cba-values?
I hope that is enough information to go on and you can help me, I would really appreciate it.
Regards
The package you are using (xarray) is already perfectly suited for this task.
dObj is an xarray.Dataset object, each contained variable (such as dObj['cba']) is an xarray.DataArray object.
You can access the data at a given set of coordinates like this:
lat = ...
lon = ...
dObj['cbd'].sel(y=lat, x=lon, method='nearest')
method='nearest' is needed as your coordinate array is unlikely to contain the requested floating point values exactly.
If you instead want to select a range of latitudes and longitudes you can do that as follows:
lat_min, lat_max = (...)
lon_min, lon_max = (...)
dObj['cbd'].sel(y=slice(lat_min, lat_max), x=slice(lon_min, lon_max))
For more information about dealing with xarray objects, have a look at the very comprehensive documentation: http://xarray.pydata.org/en/stable/index.html

Modify polygons so that they don't overlap and area stays the same

I have a set of polygons and they can overlap with each other, like this:
I want to modify them in such a way that they don't overlap and the resulting surface area stays the same. Something like this:
It is okay if the shape or the position changes. The main thing is that they should not overlap with each other and the area should not change much (I know the area changed a little in the second image but I drew it manually thus let's just assume that the areas did not change).
I am trying to do it programmatically with the help of Python. Basically I stored polygons in a PostGIS database and with the help of a script I want to retrieve them and modify them.
I am very new to GIS and thus this seems like a difficult task.
What is the correct way of doing it? Is there an algorithm that solves this kind of problems?
Take a look at ST_buffer and try passing a signed float as the second argument (degrees to reduce radius by)
SELECT buffer(the_geom,-0.01) as geom
Be careful with negative buffers as you could run into issues if the buffer size exceeds the radius, see here.
Here is what I did:
Iterated over all the polygons and found overlapping polygons. Then, I moved the polygon in different directions and found the best moving direction by calculating the minimum resulting overlapping area. Then I simply moved the polygon in that best direction until there is no overlapping area.

Pipeline to create Voronoi Meshes

I would like to implement a Maya plugin (this question is independent from Maya) to create 3D Voronoi patterns, Something like
I just know that I have to start from point sampling (I implemented the adaptive poisson sampling algorithm described in this paper).
I thought that, from those points, I should create the 3D wire of the mesh applying Voronoi but the result was something different from what I expected.
Here are a few example of what I get handling the result i get from scipy.spatial.Voronoi like this (as suggested here):
vor = Voronoi(points)
for vpair in vor.ridge_vertices:
for i in range(len(vpair) - 1):
if all(x >= 0 for x in vpair):
v0 = vor.vertices[vpair[i]]
v1 = vor.vertices[vpair[i+1]]
create_line(v0.tolist(), v1.tolist())
The grey vertices are the sampled points (the original shape was a simple sphere):
Here is a more complex shape (an arm)
I am missing something? Can anyone suggest the proper pipeline and algorithms I have to implement to create such patterns?
I saw your question since you posted it but didn’t have a real answer for you, however as I see you still didn’t get any response I’ll at least write down some ideas from me. Unfortunately it’s still not a full solution for your problem.
For me it seems you’re mixing few separate problems in this question so it would help to break it down to few pieces:
Voronoi diagram:
The diagram is by definition infinite, so when you draw it directly you should expect a similar mess you’ve got on your second image, so this seems fine. I don’t know how the SciPy does that, but the implementation I’ve used flagged some edge ends as ‘infinite’ and provided me the edges direction, so I could clip it at some distance by myself. You’ll need to check the exact data you get from SciPy.
In the 3D world you’ll almost always want to remove such infinite areas to get any meaningful rendering, or at least remove the area that contains your camera.
Points generation:
The Poisson disc is fine as some sample data or for early R&D but it’s also the most boring one :). You’ll need more ways to generate input points.
I tried to imagine the input needed for your ball-like example and I came up with something like this:
Create two spheres of points, with the same center but different radius.
When you create a Voronoi diagram out of it and remove infinite areas you should end up with something like a football ball.
If you created both spheres randomly you’ll get very irregular boundaries of the ‘ball’, but if you scale the points of one sphere, to use for the 2nd one you should get a regular mesh, similar to ball. You can also use similar points, but add some random offset to control the level of surface irregularity.
Get your computed diagram and for each edge create few points along this edge - this will give you small areas building up the edges of bigger areas. Play with random offsets again. Try to ignore edges, that doesn't touch any infinite region to get result similar to your image.
Get the points from both stages and compute the diagram once more.
Mesh generation:
Up to now it didn’t look like your target images. In fact it may be really hard to do it with production quality (for a Maya plugin) but I see some tricks that may help.
What I would try first would be to get all my edges and extrude some circle along them. You may modulate circle size to make it slightly bigger at the ends. Then do Boolean ‘OR’ between all those meshes and some Mesh Smooth at the end.
This way may give you similar results but you’ll need to be careful at mesh intersections, they can get ugly and need some special treatment.

Categories