Skip to content

Instantly share code, notes, and snippets.

@radzionc
Created August 3, 2018 10:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save radzionc/d0b2bc7661ba09972f77d60328e94725 to your computer and use it in GitHub Desktop.
Save radzionc/d0b2bc7661ba09972f77d60328e94725 to your computer and use it in GitHub Desktop.
const MAX_NUMBER_OF_PLACES = 60
const MAX_AREA_FOR_SEARCH = 60000000
const split = rectangle => {
const firstDistance = turf.distance(...rectangle.slice(0, 2))
const secondDistance = turf.distance(...rectangle.slice(1, 3))
if (firstDistance > secondDistance) {
const firstCenter = turf.midpoint(...rectangle.slice(0, 2)).geometry.coordinates
const secondCenter = turf.midpoint(...rectangle.slice(2)).geometry.coordinates
return [
[...rectangle[0], ...secondCenter ],
[...firstCenter, ...rectangle[2]]
]
} else {
const firstCenter = turf.midpoint(...rectangle.slice(1, 3)).geometry.coordinates
const secondCenter = turf.midpoint(rectangle[3], rectangle[0]).geometry.coordinates
return [
[...rectangle[0], ...firstCenter ],
[...secondCenter, ...rectangle[2]]
]
}
}
export function* selectPlace({ payload }) {
const { voronoi: { hiddenGoogleMap, cityBoundingBox }} = yield select()
let researchedRects = []
let unresearchedRects = [cityBoundingBox.flatten_()]
try {
while(unresearchedRects.length) {
const rect = unresearchedRects[0]
unresearchedRects = unresearchedRects.slice(1)
const bboxPolygon = turf.bboxPolygon(rect).geometry.coordinates[0].slice(0, 4)
const area = turf.area(turf.bboxPolygon(rect))
if (area > MAX_AREA_FOR_SEARCH) {
unresearchedRects = [
...unresearchedRects,
...split(bboxPolygon)
]
continue
}
const [minLat, minLng, maxLat, maxLng] = rect
const request = {
bounds: new google.maps.LatLngBounds(
new google.maps.LatLng(minLng, minLat),
new google.maps.LatLng(maxLng, maxLat),
),
type: payload,
}
const service = new google.maps.places.PlacesService(hiddenGoogleMap)
let placesReceived = false
let rectPlaces = []
service.nearbySearch(request, (results, status, pagination) => {
rectPlaces = [...rectPlaces, ...results]
if(pagination.hasNextPage) {
pagination.nextPage()
} else {
placesReceived = true
}
})
while(!placesReceived) {
const { voronoi: { stage } } = yield select()
if (stage !== STAGES.VORONOI) return
yield call(delay, 500)
}
if (rectPlaces.length !== MAX_NUMBER_OF_PLACES) {
const points = rectPlaces.map(p => new Point(p.geometry.location.lng(), p.geometry.location.lat()))
const contour = new Contour(bboxPolygon.map(([ x, y ]) => new Point(x, y)))
researchedRects = [...researchedRects, {
contour,
places: points,
polygons: getPolygons(rect, points)
}]
yield put(updateResearchedRectangles(researchedRects))
}
else {
unresearchedRects = [
...unresearchedRects,
...split(bboxPolygon)
]
}
}
const bboxPolygon = turf.bboxPolygon(cityBoundingBox.flatten_()).geometry.coordinates[0].slice(0, 4)
const contour = new Contour(bboxPolygon.map(([ x, y ]) => new Point(x, y)))
const places = researchedRects.take_('places').flatten_()
yield put(updateResearchedRectangles([{
contour,
places,
polygons: getPolygons(cityBoundingBox.flatten_(), places)
}]))
} catch(err) {
yield put(toggleSnackbar('fail to build voronoi diagram'))
yield put(startSearchingNewPlace())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment