Last active
July 21, 2021 05:53
-
-
Save ilantoren/dcb4dff67365c42003a212f873dc54d7 to your computer and use it in GitHub Desktop.
Mongo-Loves-Data part 2 Plotting a region on a map with individual markers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from pymongo import MongoClient | |
import pandas as pd | |
def get_data( neighborhood ): | |
data = {} | |
client = MongoClient('mongodb+srv://restaurantAppUser:restaurantAppPwd@mflix.beal2.mongodb.net/test?authSource=admin&replicaSet=atlas-a7tqy4-shard-0&readPreference=primary&appname=MongoDB%20Compass&ssl=true') | |
restaurants = client['sample_restaurants']['restaurants'] | |
# Sometimes all the work is in getting your data into the format your program requires | |
# In this example there are two queries: a) get the region coordinates for the neighborhood selected, and b) use that set of coordinates to | |
# find the restaurants within that region. | |
# Within Mongo Aggregation the command for the first is a trivial match by name, followed by some projection to get the coordinates | |
# into an immediate sub-child of the returned record. One less step for the python program code that follow | |
records = client['sample_restaurants']['neighborhoods'].aggregate([ | |
{ | |
'$match': { | |
'name': neighborhood | |
} | |
}, { | |
'$project': { | |
'name': 1, | |
# the coords are wrapped in an array so unwrap it | |
'coord': { | |
'$arrayElemAt': [ | |
'$geometry.coordinates', 0 | |
] | |
}, | |
'_id': 0 | |
} | |
}, { | |
'$addFields': { | |
# want the longitude and latitude as one array each. Use the $map | |
'long': { | |
'$map': { | |
'input': '$coord', | |
'in': { | |
'$arrayElemAt': [ | |
'$$this', 0 | |
] | |
} | |
} | |
}, | |
'lat': { | |
'$map': { | |
'input': '$coord', | |
'in': { | |
'$arrayElemAt': [ | |
'$$this', 1 | |
] | |
} | |
} | |
} | |
} | |
}]).next() | |
coord = records['coord'] | |
name = records['name'] | |
# To find the restaurants within the neighborhood is a $geoWithin query using the Polygon cordinates from the neighborhood query | |
# The query returns a list of restaurant collection documents | |
resultList = restaurants.find( {"address.coord" : {'$geoWithin': | |
{ '$geometry': {'type': 'Polygon', 'coordinates': [coord] }}}}) | |
# Use pandas DataFrame to uppack the results of geoWithin query into a DataFrame | |
results = pd.DataFrame(resultList ) | |
data['name'] = name | |
rests = pd.DataFrame(results) | |
data['restaurants'] = rests | |
data['region_lng'] = records['long'] | |
data['region_lat'] = records['lat'] | |
# extract just the address section from the restaurants object | |
address = pd.DataFrame( rests['address'] ) | |
# Initialize the long and lat for the individial restaurant markers | |
long = [] | |
lat = [] | |
# We want the address column from the addresses | |
# This could also be done as above with a $map operator | |
for i in address['address']: | |
long.append( i['coord'][0] ) | |
lat.append( i['coord'][1] ) | |
#add the long, lat to the result | |
data['long'] = long | |
data['lat'] = lat | |
#data is an object that contains objects: | |
# restaurants - the restaurant collection items contained in the region | |
# name - the name of the region which was passed into the function | |
# long and lat: an array for the restaurant marker data | |
# region_long, region_lat: two arrays for the longitude and lattitude data for the region coordinates "geometry.coordinates" | |
return data | |
# Test the code when run from python at the command line | |
print ( get_data( 'Middle Village' ) ) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment