Generate a random valid (on a road with StreetView or PhotoSphere) StreetView location in a given polygon. Used in https://locationestimatr.web.app.

Browser only

Usage

Getting 3 random locations on anywhere on earth

import randomStreetView from ' random-streetview ' ; const locations = await randomStreetView . getRandomLocations ( 3 ) ;

Get random PhotoSphere in Cyprus

import randomStreetView from ' random-streetview ' ; await randomStreetView . setParameters ( { polygon : [ [ [ 36 . 050655 , 35 . 047808 ] , [ 33 . 588766 , 34 . 364699 ] , [ 35 . 235311 , 30 . 703665 ] ] ] , type : ' photo ' , } ) ; let location = await randomStreetView . getRandomLocation ( ) ;

Documentation

Parameters

polygon (Array | google.maps.Polygon | false) default: false

Polygon can be an array of paths, a Google Maps API Polygon object, or false. If it's false the entire world is considered. Array containing paths, which are arrays containing coordinates.

Array example:

[[[53.629774, 3.428422], [53.655826, 8.350297], [49.337423, 8.745805], [48.383385, 1.494829]]]

These are 4 points describing one area containing the Benelux. A polygon can contain multiple disjointed areas.

enableCaching (Boolean) default: true

Whether to use localStorage caching for getting StreetView coverage of the tile.

endZoom (Integer) default: 14

At what zoom level should the algorithm try to find a valid road/PhotoSphere. Zoom levels can be visualized here: https://www.maptiler.com/google-maps-coordinates-tile-bounds-projection/. Should be between 12 and 22, however 12 is probably too low, and 22 is overkill. A small polygon can benefit from a zoom level of 18 to prevent locations being picked just outside of the polygon.

cacheKey (String|false) default: false

When enableCaching is true, and the list of coordinates is large, it's a good idea to set this parameter. This will determine what key should be used in the cache for the given polygon, a different polygon should have a different key. When no cache key is given one will be generated from the coordinates.

type ('sv'|'photo'|'both') default: 'sv'

What type of StreetView to look for. 'sv' looks for standard StreetView roads, 'photo' looks for PhotoSpheres only, 'both' will allow both.

distribution ('weighted'|'uniform') default: 'weighted'

How the algorithm should randomly choose a location. Uniform is randomness based on area. Weighted has more chance to go to a tile with a higher amount of StreetView coverage.

As can be seen in the image above, Russia has much more StreetView coverage in the west. With uniform distribution a location in the east is as likely as a location in the west, while with weighted distribution a location in the west will be more likely, because there is much more StreetView coverage there.

If you already use the Google api on your page (with the geometry library enabled), you can pass here so it's not loaded twice. If set to false, random-streetview will load the Google Maps API itself.

Note: a warning might show up that no API key is set, this is not a problem as only the geometry functions are used from the Google API.

Methods

async setParameters({ polygon: false, enableCaching: true, endZoom: 14, cacheKey: false, type: 'sv', distribution: 'weighted', google` : void })

Sets parameters listed above. It's not needed to call this before calling getRandomLocation. Returns Promise.

async getRandomLocation() : [lat (Number), lng (Number) | false]

Returns a Promise with a random location given the parameters. If setParameters hasn't been called it returns a random location on earth. If no valid location could be found in the polygon provided, it will return false.

async getRandomLocations(nLocations, onLocationCallback) : [[lat (Number), lng (Number)]|false]

nLocations : Amount of locations to find

onLocationCallback : Gets called for every location that's found, can be useful for when not all locations are needed at once.

Returns a Promise with the given amount of locations in an array. If no valid location could be found in the polygon provided, it will return an array of false.

setHighCpuUsage() : void

Sets normal operating mode, can cause some lag on slower devices when other CPU intensive ui tasks are being performed.

setLowCpuUsage() : void

Adds timeouts to algorithm. This will make finding a location much slower, and shouldn't be used permanently.

How it works

The world map is divided in map tiles, each with an x and y coordinate and a zoom level.

This algorithm will start at the smallest tile which fully contains the given polygon (polygon shown below), which in the case of the Benelux polygon is tile (16, 10, 5). Then it will zoom into that tile, which results in 4 subtiles (32,20,6), (33, 20, 6), (32, 21, 6) and (33, 21, 6). A random valid tile is picked based on the distribution type and the zoom process continues. A valid tile is a tile that has the right StreetView coverage (PhotoSphere or roads) and intersects the polygon. When the endZoom zoom level is reached, the final tile is found. In this tile a random road or PhotoSphere pixel is chosen, and turned into a coordinate.