Giter Club home page Giter Club logo

random-streetview's Introduction

random-streetview

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);
// example locations contents: 
// [[9.096418449685814, -2.484712600708008],
// [66.93355785447132, 21.258974075317383],
// [11.362409446559152, 76.77838325500488]]

Get random PhotoSphere in Cyprus

import randomStreetView from 'random-streetview';
await randomStreetView.setParameters({
    //Polygon contains Cyprus:
    polygon: [[[36.050655, 35.047808], [33.588766, 34.364699], [35.235311, 30.703665]]],
    type: 'photo',
});
let location = await randomStreetView.getRandomLocation();
// example locations contents: 
// [34.956658755288984, 32.30649948120117]

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.

Distribution example 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.

google (Google Maps JS API|false) default: false

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.

workingsexample1

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.

workingsexample

random-streetview's People

Contributors

craftycram avatar ruurdbijlsma avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

random-streetview's Issues

Can't seem to get this package to work.

Keep running into an error supposedly stemming from Google.js inside of this package, but I would assume it's in each js file too.

Error: Class extends value [object Object] is not a constructor or null

This happens even when just importing the package.
EventEmitter is underlined in Google.js when checking logs.

Can't read property "LatLng" of undefined

I keep running into issues when I add the google parameter, and the latest one is what you see in the title. I've tried inputting the embed api, the regular javascript maps api, added the geometry library, etc. Am I just inputting this wrong or does this expect a specific endpoint and params? My code is below.

I'm also having trouble seeing how/if we're able to render the map through the getRandomLocation function or if we strictly use the coordinates it gives back in a new map object through Google.

import Head from "next/head";
import randomStreetView from "random-streetview";
import { useState, useEffect } from "react";

export default function Home() {
  const [url, setUrl] = useState([]);

  const getData = async () => {
    randomStreetView.setParameters({
      enableCaching: true,
      endZoom: 14,
      cacheKey: false,
      type: "sv",
      distribution: "weighted",
      google: `https://www.google.com/maps/embed/v1/streetview?key=[myapikey]`,
    });
    const location = await randomStreetView.getRandomLocation();
    setUrl(location);
  };
  useEffect(() => {
    getData();
    return () => {
      console.log(location);
    };
  }, []);

  return (
    <div className="container">
      <Head>
      </Head>

      {url.length > 0 ? (
        <iframe
          frameBorder="none"
          allowFullScreen
          src={`https://www.google.com/maps/embed/v1/streetview?key=AIzaSyArsb4Om72FY0mvhkBzPNcuPczOhHOStfo&location=${url[0]},${url[1]}`}
        ></iframe>
      ) : null}

          <p
            onClick={getData}
            className="description"
          >{`lat: ${url[0]} long: ${url[1]}`}
         </p>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.