Converting a geopandas geometry into a shapleys polygon - gis

I am extremely new to python in general, but come from a decent programming background in Fortran and Matlab. I'm trying to figure out what seems to be a simple task:
I am importing a Shapefile using GeoPandas read_file command. It comes in with no problem, and includes the geometry column that contains the polygon represented by all the vertices as you would expect. The data is a single row.
What I need is a Shapely's Polygon to pass into py3dep so I can gather the spatial rasters I need, and I cannot figure out how to translate the geometry entry into a polygon.
The solution has to be simple, but I've been searching for hours, trying a thousand different things, all to no avail. If anyone could help with a simple demonstration I'd be eternally grateful.
Here's a snippet of what I'm trying to do, I've verified the code works when I pass it the tuple, and fails if I try to pass "shape" to "geom" as shape is not a shapelys polygon. (I understand this is a lame attempt and is just shown as "what I'm trying to do")
UPDATED CODE BELOW TO WORKING based on solution provided by #PaulH
import py3dep
import geopandas as gpd
shape = gpd.read_file("inputshape.shp")
print(shape.type)
geom = shape.loc[0, 'geometry']
dem = py3dep.get_map("DEM", geom, resolution=10, geo_crs="epsg:4326", crs="epsg:3857", output_dir="raster")

Related

Prepping geodata for interactive geo viz using Bokeh - slow to JSON

I'm trying to create a geo viz using this data which maps out all of the zip codes in NYC: https://data.cityofnewyork.us/Health/Modified-Zip-Code-Tabulation-Areas-MODZCTA-Map/5fzm-kpwv. I've used geopandas to read the data as a geodataframe, used shapely.wkt - loads on the multipoloygon, & set the appropriate column as the geometry.
I then uploaded this tree census data (https://data.cityofnewyork.us/Environment/2015-Street-Tree-Census-Tree-Data/uvpi-gqnh) into a df and merged the two on the zipcode column (I renamed cols myself as datasets used different terms).
My goal is to create an interactive geo viz using Bokeh, which I understand uses GEOJson. I've used the following code to achieve: JNB screenshot of code
However, it is taking an exceedingly long time to run the code:
nyc_trees = json.loads(nyc_trees.to_json())
I've tried ujson as well, but it hasn't helped with the timing. Is there a way to speed this up or another work around?

Leaflet markercluster: How can I change the bounds of the markercluster?

For university I create a webmap using leaflet - it´s about migration in Iraq. In the map I have one choropleth-layer with coordinates from a json (Iraq with its gouvernorates) with a value for each gouvernorate. Additionally I added a layer with markers from another json to the map. This json only contains the coordinates for markers with a value for each marker. I implemented a leaflet markerclustering where all child markers are summarized and the sum is shown in the parent-icon - although the sum isn´t correct until now, I think it is working, so far... I am allready looking for the mathematical error...
Now, I would like to change the bounds for the marker-clustering (currently I think they are built automatically and randomly by leaflet) to the bounds of the gouvernorates in the first json of Iraq. The aim is a regionbound clustering for the gouvernorates of Iraq. There are some examples on the web and I have tried a lot, but it doesn´t work...
maybe somebody here can help me.. If you have any questions or need further explanation, just tell me!
Sources:
- json code in an js-file "iraq_09_14.js" with the gouvernorate-polygon-coordinates of Iraq
json code in an js-file "target-location_09_14.js" with marker-polygones and value for each marker
this is the js-code where I create the leaflet map
this is the js-code where I create the markerclusters with the sum of the values
I would like to change the bounds for the marker-clustering [...] to the bounds of the gouvernorates in the first json of Iraq.
Then create one instance of MarkerClusterGroup per governorate, and add each marker to the corresponding cluster group.
This json only contains the coordinates for markers with a value for each marker.
You should really pre-process the data, so each marker has information about what governorate it belongs to. You might want to do point-in-polygon geoprocessing, via Turf or otherwise.
(currently I think [the clusters] are built automatically and randomly by leaflet)
They are not random, the hierarchical greedy clustering algorithm is deterministic. You can read more at https://www.mapbox.com/blog/supercluster/

New to Python - proficient with Matlab: getting error "IndexError: list index out of range"

As the title says, I'm proficient with Matlab and already have this function written there and it works great. I wanted to learn a new language and I've been pointed to Python so I figured I would write a simple function to get used to the syntax of Python and have something to validate what I've done. I wrote the function "Xfcn" (which is non-dimensional mass flow in rocket problems) and it gives me the correct number if I only use one value. Now, I'd like to plot the X-function versus Mach and validate with my Matlab version. I need to loop through some Mach vector then plot it. Plotting comes later. I'm getting the error mentioned above and I think it's a simple indexing problem, although I can't seem to figure out what it is. I've looked here and on Python's documentation center so hopefully we can resolve this quickly. I've also checked the "type" of "i", printed the range(len(Ms)) and get 0-49, by 1's, as I expect with the particular values of Ms 0-1 by equally spaced increments, also as I expect, so I cannot figure out where my error is. My code is below.
from Xfcn import Xfcn
import pylab as pyl
import numpy as np
Ms = np.linspace(0,1,endpoint=True)
X = []
for i in range(len(Ms)):
X[i][0] = Xfcn(Ms[i])
print X
print 'Done.'
Thanks for the help!
BL
You created x as a single dimensional list and are trying to access it as if it was multi dimensional

Storing 3d shapes in sql server using geometry data type and WKT

I'm looking at the geometry data type in Sql Server 2008 and it looks interesting but the documentation does not seem that good. Would I be able to store cones, cylinders and spheres in the WKT format? These features traditionally have a radius and not hundreds of points.
To the best of my knowledge your are going to have to use an external application to render your shape as a large number of points. See this blog for a technique for rendering circles.
One possibility to consider is a CLR proc to render the shapes you need and a view with indexes. I don't know how well that will perform, but it just might work.
sorry for the late reply. You could always write your own User-Defined-Type called Circle, with two properties namely Centroid and Radius.
Inside the newly formed UDT, create a method that takes the properties Centroid (Point3D), and Radius (Double). After this, create a method that uses both SqlGeometry and SqlGeometryBuilder to build the newly formed object.
First, create a Point instance of Geometry. Inherit the Centroid values from the class object, then, create another Geometry Polygon that's derived from the Point object, and STBuffer(Radius) it.
Below is my example: (written in 30min)
public SqlGeometry ToSQLGeometry()
{
int srid = this.SRID; // i.e. 4326
SqlGeometry geom = new SqlGeometry();
SqlGeometryBuilder gb = new SqlGeometryBuilder();
OpenGisGeometryType pt = OpenGisGeometryType.Point;
gb.SetSrid(srid);
gb.BeginGeometry(pt);
gb.BeginFigure(this.Centroid.X, this.Centroid.Y, this.Centroid.Z, this.Centroid.M);
gb.EndFigure();
gb.EndGeometry();
geom = gb.ConstructedGeometry;
geom = geom.MakeValid(); // Optional for Point data
SqlGeometry geomCircle = new SqlGeometry();
geomCircle = geom.STBuffer(this.Radius);
return geomCircle;
}
When you've done this in VS2010 by using the CLR project type, you can deploy it to your database.
In SQL, you can call the object as such:: Parse(X Y Z M,R)
declare #c Circle
set #c = Circle::Parse('5 6 7 8,2')
select 'Circle', #c.ToString(), #c.ToSQLGeometry()
Had a quick look around and found this MSDN page on Spatial Samples. It covers all the Methods to enter data in WKT, WKB & XML(GML) as well as functions to view the in Human Readable form. It also covers MakeValid, STIsValid & STSrid.
There looks to be a fair few SQL examples that you may find useful

Saving and restoring geometries in OpenLayers

Context: I'm a just-hours-old newbie at OpenLayers, please be gentle.
Fundamentally, I have a map with some drawn objects on it. If I understand things correctly, I have a number of OpenLayer.Feature.Vector (layers?) with a number of OpenLayer.Geometry "things" (like LinearRing) on it.
At the moment, I seem to be able to get a nice representation of the geometry, using .toString(). Yes, I suspect I'm doing it wrong -- feel free to point me in the right direction.
This yields a very human readable, and database storable, strings such as:
POINT(-104.74560546875 44.2841796875)
POLYGON((-96.52783203125 44.6796875,-96.52783203125 45.734375,-92.22119140625 45.734375,-92.22119140625 44.6796875,-96.52783203125 44.6796875))
LINESTRING(-105.71240234375 44.6796875,-106.06396484375 42.658203125,-103.55908203125 42.7021484375,-103.47119140625 45.55859375,-104.65771484375 45.20703125)
Is there an inverse way of getting these back into the object format from whence they came?
I'd love to be using JSON, but can't seem to get GeoJSON to accept my OpenLayer.Feature.Vector object (which is what the CLASS_NAME property says it is when I peer inside).
Many thanks.
The Openlayers.Geometry objects’ toString method converts them nicely to WKT (Well-Known Text). If you use a GIS layer on top of your database (like PostGIS for PostGres, SQL Spatial for SQL Server, Spatialite for SQLite, etc.), they should offer functions that enable you to process WKT.
But if you want to convert that WKT to a new Openlayers.Geometry object (in the browser), you can use the fromWKT function:
var point = OpenLayers.Geometry.fromWKT('POINT(-104.74560546875 44.2841796875)');
alert(point.toString()); // POINT(-104.74560546875 44.2841796875)
Here, the variable point will now contain a new Openlayers.Geometry object, which has the same properties as the original one you used toString() on.
If you pass an array to the fromWKT function, it will return a GeometryCollection containing all the generated geometries.
var geometryTexts = [
'POINT(-104.74560546875 44.2841796875)'
, 'POLYGON((-96.52783203125 44.6796875,-96.52783203125 45.734375,-92.22119140625 45.734375,-92.22119140625 44.6796875,-96.52783203125 44.6796875))'
, 'LINESTRING(-105.71240234375 44.6796875,-106.06396484375 42.658203125,-103.55908203125 42.7021484375,-103.47119140625 45.55859375,-104.65771484375 45.20703125)'
],
collection = OpenLayers.Geometry.fromWKT(geometryTexts);
After this, collection.toString() should yield the following:
GEOMETRYCOLLECTION(POINT(-104.74560546875 44.2841796875),POLYGON((-96.52783203125 44.6796875,-96.52783203125 45.734375,-92.22119140625 45.734375,-92.22119140625 44.6796875,-96.52783203125 44.6796875)),LINESTRING(-105.71240234375 44.6796875,-106.06396484375 42.658203125,-103.55908203125 42.7021484375,-103.47119140625 45.55859375,-104.65771484375 45.20703125))
In my other answer, I went with WKT because you mentioned it. I now see that you seem to prefer GeoJSON.
To convert a vector layer or an Openlayers.Geometry object to a GeoJSON string, you should use the OpenLayers.Format.GeoJSON.write function:
var geoJSON = new OpenLayers.Format.GeoJSON(),
geoJSONText = geoJSON.write(geometryObject);
Note that you should be able to pass your object to this function, since (according to documentation) it accepts an OpenLayers.Feature.Vector as well as a OpenLayers.Geometry or an array of features.
Conversely, when you’ve got a GeoJSON string, you can convert that back to an object using the OpenLayers.Format.GeoJSON.read function:
var geometry = geoJSON.read(geoJSONText, 'Geometry');
The second parameter lets you indicate which type of object you’d like returned. Read the docs linked to for more information.
Also, take a look at this demo for a more extensive example. (View the source of the page to see how they’re doing it).