Skip to content

Instantly share code, notes, and snippets.

@ilantoren
Last active July 21, 2021 05:53
Show Gist options
  • Save ilantoren/dcb4dff67365c42003a212f873dc54d7 to your computer and use it in GitHub Desktop.
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
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