Map multiple geospatial polygons to their nearest lat/long point in a different table using GeoPandas or other Python tool - gis

I've got a list of voting precinct geospatial polygons that need to join to a different table with just lat/long points for each zip code. How can I join each of the precinct polygons to its nearest zip code lat/long point?
This article has helped me to build this script which quickly maps each of my points to the coordinate polygon it fits inside of:
import pandas as pd
import geopandas as gpd
df_zip = pd.read_csv('zipdata.csv')
gdf_pts = gpd.GeoDataFrame(df_zip, geometry=gpd.points_from_xy(df_zip.Longitude, df_zip.Latitude))
precinct_file = 'precinctdata.geojson'
gdf_coord = gpd.read_file(precinct_file)
sjoined_listings = gpd.sjoin(gdf_pts, gdf_coord, op=”within”)
# where zipdata.csv includes a latitude and longitude column along w/ other zip code data
# and precinctdata.geojson is a geojson file that includes polygons for over 100k voting precincts
Now instead of mapping each zip point to the precinct polygon it belongs to, I want to map each polygon to its nearest point so that ALL precinct polygons will have a corresponding zip code point that is the nearest point to it. Many points will map up to multiple polygons as there's over 140k precincts and less than 42k zip codes in the dataset.
I've found some similar questions here and here but weren't able to fit it into my script -- I'm new to GIS but fixed on getting going with it.

Related

Geocoding - get all records within a boundry

Lets say I have a database of locations (countries, regions, cities, towns) with their lat/long co-ordinates.
E.g. I have the co-ordinates for England 52.16045, -0.70312
Is there a way for me to return all locations within the bounds of England if all I have are lat/long?
Do I need to polygonise the location...if so how would I do that if all I have are lat/longs.
For the record the database is Mysql.
Some guidance would be appreciated.
If you have a polygon with the boundary of the state you could use a ST_CONTAINS feature of mysql geometry for find al the points inside the polygon
Assuming you have a table (points) the contain the points and polygons with polygon, and each polygon is based on a polygon.name
you could use
SELECT points.col1
FROM polygons
INNER points ON ST_CONTAINS(polygons.geom, Point(points.longitude, points.latitude))
AND polygons.name = 'Your_name';
the ST_CONTAING just check if a geometry is contained inside one other

Check if string address X is within string address Y, using REST API complex polygon

I was looking for an API but struggling mightily. My approach was to get complex polygon like in the image below for australia:
One user will come and input me string addresses of X like:
Sydney, Australia
And another user gives me string address of Y like:
Australia
Is there an API that I can hit, gives me complex polygon for the address? The closest I'm getting is getting bounding box (north, west, south, and east lat/lng) by hitting API - https://dev.virtualearth.net/REST/v1/Locations?q=australia&key=MY_KEY_HERE
Once I get the complex polygon, I then will try to test if these complex polygons intersect to answer my question wtih: Yes, X value of "Sydney, Australia" is within Y value of "Australia".
To get polygon for country or city you can use Geodata API.
Here is documentation for GeoDataAPIManager that is part v8 of Map Control - Spatial Data Services Module: https://msdn.microsoft.com/en-us/library/mt712862.aspx , you can see code sample on v8 iSDK: https://www.bing.com/api/maps/sdkrelease/mapcontrol/isdk/sdsloadsingleboundary#overview
Once you have boundaries, you can use Spatial Math Module, to check for intersection. See this code sample: http://bingmapsv8samples.azurewebsites.net/#Find%20all%20counties%20that%20intersect%20a%20line

Given two point's latitude and longitude, computing coordinates of point in between

I'm trying to generate some annotations on a map. Currently, I'm using openstreetmap but the query is general. I have two end points on a map and a corpus of few selected points I would like to highlight.
The two endpoints are given in the form lat, long
<walkSteps>
<distance>9.742464221826811</distance>
<streetName>5th St NW</streetName>
<absoluteDirection>EAST</absoluteDirection>
<stayOn>false</stayOn>
<bogusName>false</bogusName>
<lon>-84.3937361115149</lon>
<lat>33.77692965678444</lat>
<elevation/>
</walkSteps>
<walkSteps>
<distance>508.2608917548245</distance>
<relativeDirection>LEFT</relativeDirection>
<streetName>Fowler St NW</streetName>
<absoluteDirection>NORTH</absoluteDirection>
<stayOn>false</stayOn>
<bogusName>false</bogusName>
<lon>-84.39363494600667</lon>
<lat>33.77692904176358</lat>
<elevation/>
</walkSteps>
My aim is to highlight those points on the map, which are present in the corpus and lie in the line connecting these two points.
How can I go about querying the corpus for the same? Annotating on map given lat, lng is not an issue
Rounding errors will prevent you from directly doing as you want. What you should be doing instead is determining the great-circle path between the two end points and highlighting those members of the corpus which are within a certain distance of the great circle route. This is known as the cross-track distance or cross-track error. Formulas for computing the cross-track distance can be found at one of the standard reference sites for geospatial equations but there are others as well.. The problem then becomes one of searching for points in the corpus which are close enough to the great circle path between the two end points.

Google Maps/OSM - Finding records within 100 miles of an area (not a point)

I would like to find all points that are within N miles of a given area.
E.g. the area is California: Find all points that are within 50 miles of the border of California (not the middle of California).
When using Google Maps the distance is calculated using 'the middle' of the given location, but I need to calculate the distance using the borders of the given location. The location could be any zip code, city or country.
Could that be done by drawing a polygon using California's coordinates on a map and calculate the distance to location B using the points of the polygon?
Is there a more elegant solution to this? Any ideas?
Thanks!
I'm not sure if I understand your requirements completely, but I will give it a try with different interpretations:
1. You want to filter own map points:
This can be done with any GIS or a own service that offers a call like my_points_in_area(bbox). Bbox means here boundingbox and is the 2x lat/lon pair describing the rectangle around your given centerpoint. If you want to be accurate and really just deliver whats within 100km, you might need to test the distance to the POIs once more, as the rectangle will also include points that are a bit more far away.
2. You want to filter OSM data:
You might use a reverse-geocoding service as Nominatim to get informations about points of interests that are within this distance: http://wiki.openstreetmap.org/wiki/Nominatim
Otherwise import the OSM data using osmosis to a PostGIS DB. AFAIK there is (currently) no DB tool for Oracle: http://wiki.openstreetmap.org/wiki/Oracle
I'm sorry if I missed your question, but then please add more details :)

2D Open Street Map Data Representation in Meters

I am in the process of converting OSM data into an open source Minecraft port (written in javascript - voxel.js). The javascript rendition is written such that each voxel (arbitrarily defined as a cubic meter) is created as a relation from a single point of origin (x,y,z)(0,0,0).
As an example, if one wanted to create a cubic chunk of voxels, one would simply generate voxels as a relation to the origin (0,0,0) : [(0,0,0),(1,0,0), (0,1,0)...].
My question is this: I've exported OSM data, and the standard XML output (.osm) plots nodes in latitude and longitude. My initial thought is that I can create a map by calculating the distance of each node from an arbitrary point of origin (0,0,0) = (37.77559, -122.41392) using the Haversine formula, convert the distance to meters, find the bearing, and plot it as a relation to (0,0,0).
I've noticed, however, that there are a number of other export formats available: (.osm.pbf, .osm2pgsql, .imposm). I'm assuming they plot nodes in a similar fashion (lat, lng), but some of them have the ability to import directly into a database (e.g. PostgreSQL).
I've heard of people using PG add-ons like PostGIS, but (as this is my first dive into GIS) I'm unfamiliar with their capabilities and whether something like PostGIS would help me in plotting OSM data into a 2D voxel grid.
Are there functions within add-ons like PostGIS that would enable me to dynamically calculate the distance between two Lat/Lng points, and plot them in an x,y fashion?
I guess, fundamentally, my question is: if I create a script that plots OSM data into an x,y grid would I be reinventing the wheel, or is there a more efficient way to do this?
You need to transform from the spherical coordinates (LatLon, using WGS84) to cartesian coordinates, like googles spherical mercator.
In pseudo code
transform(double lat, double lon) {
double wgs84radius = 6378137;
double shift = PI * wgs84radius;
double x = lon * shift / 180;
double y = log(tan((90+lat)*PI/360)/ (PI/180);
return {x,y}
}
This is the simplest way. Keep in mind that Lat/Lon are angles, while x and y are distances from (0/0)
The OSM data is by default in the WGS84 (EPSG:4326) projection which is based on an ellipsoidal Earth and measures latitude and longitude in degrees.
Most map tiles are generated in the EPSG:900913 "Google" spherical mercator projection. This projection is based on a spherical Earth and latitude and longitude are measured in metres from the origin.
It really seems like the 900913 projection will fit quite nicely with your requirements.
Here is some code for converting between the two.
You might like to consider using osm2psql. During the import process all of the OSM map data is converted to the 900913 projection. What you are left with is a database of all the nodes, lines and polygons of the OSM map data in an easy to access Postgres database.
I was initially intimidated by this process but it is really quite straightforward and will give you lots of flexibility when it comes to using the OSM data.