Libreria di geometrie

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.
  1. Panoramica
  2. Concetti di geometria sferica
    1. Funzioni relative a distanza e area
    2. Funzioni di navigazione
  3. Codifica della geometria
  4. Funzioni per poligoni e polilinea
    1. containsLocation()
    2. isLocationOnEdge()

Panoramica

I concetti contenuti in questo documento si riferiscono alle funzionalità disponibili solo nella libreria google.maps.geometry. Questa libreria non viene caricata per impostazione predefinita quando carichi l'API Maps JavaScript, ma deve essere specificata in modo esplicito tramite l'utilizzo di un parametro bootstrap libraries. Per maggiori informazioni, consulta la Panoramica delle librerie.

La libreria di geometrie dell'API Maps JavaScript fornisce utilità per il calcolo dei dati geometrici sulla superficie terrestre. La libreria include tre spazi dei nomi:

  • spherical contiene utilità di geometria sferiche che consentono di calcolare angoli, distanze e aree da latitudini e longitudini.
  • encoding contiene utilità per la codifica e la decodifica dei percorsi polilinea in base all'algoritmo polilinea codificato.
  • poly contiene funzioni di utilità per i calcoli che coinvolgono poligoni e polilinee.

La libreria google.maps.geometry non contiene classi, ma contiene metodi statici negli spazi dei nomi precedenti.

Concetti di geometria sferica

Le immagini all'interno dell'API Maps JavaScript sono bidimensionali e "piatte". La Terra, invece, è tridimensionale e spesso è approssimata come uno sferoide oblato o più come una sfera. All'interno dell'API di Maps utilizziamo una sfera e per rappresentare la Terra su una superficie piana bidimensionale, come lo schermo del tuo computer, l'API di Maps utilizza una proiezione.

All'interno delle proiezioni 2D, l'aspetto talvolta può ingannare. Poiché la proiezione della mappa richiede necessariamente una distorsione, spesso non è possibile utilizzare una semplice geometria euclidiana. Ad esempio, la distanza più breve tra due punti di una sfera non è una linea retta, ma un grande cerchio (un tipo di geodetica) e gli angoli che compongono un triangolo sulla superficie di una sfera sommano i 180 gradi.

A causa di queste differenze, le funzioni geometriche su una sfera (o sulla sua proiezione) richiedono l'uso della metria sferica per calcolare i costrutti come distanza, intestazione e area. Le utilità per calcolare questi costrutti geometrici sferici sono contenute nello spazio dei nomi google.maps.geometry.spherical dell'API di Google Maps. Questo spazio dei nomi fornisce metodi statici per il calcolo di valori scalari da coordinate sferiche (latitudini e longitudini).

Funzioni per distanza e area

La distanza tra due punti è la lunghezza del percorso più breve tra loro. Questo percorso più breve è chiamato geodetica. Su una sfera tutte le geodetiche sono segmenti di un grande cerchio. Per calcolare questa distanza, chiama computeDistanceBetween(), passando due oggetti LatLng.

Puoi utilizzare computeLength() per calcolare la lunghezza di un dato percorso se hai più sedi.

I risultati della distanza sono espressi in metri.

Per calcolare l'area (in metri quadrati) di un'area poligonale, chiama computeArea(), passando l'array di LatLng oggetti che definiscono un anello chiuso.

Quando navighi su una sfera, un'intestazione è l'angolo di una direzione da un punto di riferimento fisso, di solito vero nord. All'interno dell'API di Google Maps, un'intestazione è definita in gradi da vero nord, dove le intestazioni sono misurate in senso orario da vero nord (0 gradi). Puoi calcolare questa intestazione tra due località con il metodo computeHeading(), passando due oggetti from e to LatLng.

Data un'intestazione particolare, una località di origine e la distanza da percorrere (in metri), puoi calcolare le coordinate di destinazione utilizzando computeOffset().

Dato due oggetti LatLng e un valore compreso tra 0 e 1, puoi anche calcolare una destinazione tra di loro utilizzando il metodo interpolate(), che esegue l'interpolazione sferica sferica tra le due località, dove il valore indica la distanza frazionaria percorre il percorso dall'origine alla destinazione.

L'esempio seguente crea due polilinee quando fai clic su due punti sulla mappa (una geodetica e una "linea" che collega le due località) e calcola l'intestazione per viaggiare tra i due punti:

TypeScript

// This example requires the Geometry library. Include the libraries=geometry
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">

let marker1: google.maps.Marker, marker2: google.maps.Marker;
let poly: google.maps.Polyline, geodesicPoly: google.maps.Polyline;

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: { lat: 34, lng: -40.605 },
    }
  );

  map.controls[google.maps.ControlPosition.TOP_CENTER].push(
    document.getElementById("info") as HTMLElement
  );

  marker1 = new google.maps.Marker({
    map,
    draggable: true,
    position: { lat: 40.714, lng: -74.006 },
  });

  marker2 = new google.maps.Marker({
    map,
    draggable: true,
    position: { lat: 48.857, lng: 2.352 },
  });

  const bounds = new google.maps.LatLngBounds(
    marker1.getPosition() as google.maps.LatLng,
    marker2.getPosition() as google.maps.LatLng
  );

  map.fitBounds(bounds);

  google.maps.event.addListener(marker1, "position_changed", update);
  google.maps.event.addListener(marker2, "position_changed", update);

  poly = new google.maps.Polyline({
    strokeColor: "#FF0000",
    strokeOpacity: 1.0,
    strokeWeight: 3,
    map: map,
  });

  geodesicPoly = new google.maps.Polyline({
    strokeColor: "#CC0099",
    strokeOpacity: 1.0,
    strokeWeight: 3,
    geodesic: true,
    map: map,
  });

  update();
}

function update() {
  const path = [
    marker1.getPosition() as google.maps.LatLng,
    marker2.getPosition() as google.maps.LatLng,
  ];

  poly.setPath(path);
  geodesicPoly.setPath(path);

  const heading = google.maps.geometry.spherical.computeHeading(
    path[0],
    path[1]
  );

  (document.getElementById("heading") as HTMLInputElement).value =
    String(heading);
  (document.getElementById("origin") as HTMLInputElement).value = String(
    path[0]
  );
  (document.getElementById("destination") as HTMLInputElement).value = String(
    path[1]
  );
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// This example requires the Geometry library. Include the libraries=geometry
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">
let marker1, marker2;
let poly, geodesicPoly;

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: 34, lng: -40.605 },
  });

  map.controls[google.maps.ControlPosition.TOP_CENTER].push(
    document.getElementById("info")
  );
  marker1 = new google.maps.Marker({
    map,
    draggable: true,
    position: { lat: 40.714, lng: -74.006 },
  });
  marker2 = new google.maps.Marker({
    map,
    draggable: true,
    position: { lat: 48.857, lng: 2.352 },
  });

  const bounds = new google.maps.LatLngBounds(
    marker1.getPosition(),
    marker2.getPosition()
  );

  map.fitBounds(bounds);
  google.maps.event.addListener(marker1, "position_changed", update);
  google.maps.event.addListener(marker2, "position_changed", update);
  poly = new google.maps.Polyline({
    strokeColor: "#FF0000",
    strokeOpacity: 1.0,
    strokeWeight: 3,
    map: map,
  });
  geodesicPoly = new google.maps.Polyline({
    strokeColor: "#CC0099",
    strokeOpacity: 1.0,
    strokeWeight: 3,
    geodesic: true,
    map: map,
  });
  update();
}

function update() {
  const path = [marker1.getPosition(), marker2.getPosition()];

  poly.setPath(path);
  geodesicPoly.setPath(path);

  const heading = google.maps.geometry.spherical.computeHeading(
    path[0],
    path[1]
  );

  document.getElementById("heading").value = String(heading);
  document.getElementById("origin").value = String(path[0]);
  document.getElementById("destination").value = String(path[1]);
}

window.initMap = initMap;
Visualizza l'esempio

Prova Esempio

Metodi di codifica

I percorsi all'interno dell'API Maps JavaScript sono spesso specificati come oggetti Array di LatLng. Tuttavia, il passaggio di questo tipo di array è spesso ingombrante. Puoi invece utilizzare l'algoritmo di codifica polilinea di Google per comprimere un determinato percorso, che in seguito puoi decomprimere tramite la decodifica.

La libreria geometry contiene uno spazio dei nomi encoding per le utilità per codificare e decodificare le polilinee.

Il metodo statico encodePath() codifica il percorso specificato. Puoi passare un array di LatLng o un MVCArray (che viene restituito da Polyline.getPath()).

Per decodificare un percorso codificato, chiama decodePath() passando il metodo seguito dalla stringa codificata.

L'esempio seguente mostra una mappa di Oxford, in Mississippi. Se fai clic sulla mappa, viene aggiunto un punto a una polilinea. Poiché la polilinea è strutturata, la sua codifica viene visualizzata sotto.

TypeScript

// This example requires the Geometry library. Include the libraries=geometry
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 14,
      center: { lat: 34.366, lng: -89.519 },
    }
  );
  const poly = new google.maps.Polyline({
    strokeColor: "#000000",
    strokeOpacity: 1,
    strokeWeight: 3,
    map: map,
  });

  // Add a listener for the click event
  google.maps.event.addListener(map, "click", (event) => {
    addLatLngToPoly(event.latLng, poly);
  });
}

/**
 * Handles click events on a map, and adds a new point to the Polyline.
 * Updates the encoding text area with the path's encoded values.
 */
function addLatLngToPoly(
  latLng: google.maps.LatLng,
  poly: google.maps.Polyline
) {
  const path = poly.getPath();

  // Because path is an MVCArray, we can simply append a new coordinate
  // and it will automatically appear
  path.push(latLng);

  // Update the text field to display the polyline encodings
  const encodeString = google.maps.geometry.encoding.encodePath(path);

  if (encodeString) {
    (document.getElementById("encoded-polyline") as HTMLInputElement).value =
      encodeString;
  }
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// This example requires the Geometry library. Include the libraries=geometry
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 14,
    center: { lat: 34.366, lng: -89.519 },
  });
  const poly = new google.maps.Polyline({
    strokeColor: "#000000",
    strokeOpacity: 1,
    strokeWeight: 3,
    map: map,
  });

  // Add a listener for the click event
  google.maps.event.addListener(map, "click", (event) => {
    addLatLngToPoly(event.latLng, poly);
  });
}

/**
 * Handles click events on a map, and adds a new point to the Polyline.
 * Updates the encoding text area with the path's encoded values.
 */
function addLatLngToPoly(latLng, poly) {
  const path = poly.getPath();

  // Because path is an MVCArray, we can simply append a new coordinate
  // and it will automatically appear
  path.push(latLng);

  // Update the text field to display the polyline encodings
  const encodeString = google.maps.geometry.encoding.encodePath(path);

  if (encodeString) {
    document.getElementById("encoded-polyline").value = encodeString;
  }
}

window.initMap = initMap;
Visualizza l'esempio

Prova Esempio

Funzioni per poligoni e polilinea

Lo spazio dei nomi poly della libreria di geometrie contiene funzioni di utilità che determinano se un determinato punto si trova all'interno o vicino a un poligono o a una polilinea.

contiene la località (())

containsLocation(point:LatLng, polygon:Polygon)

Per verificare se un determinato punto rientra all'interno di un poligono, passa il punto e il poligono a google.maps.geometry.poly.containsLocation(). Le funzioni restituiscono true se il punto si trova all'interno del poligono o sul suo bordo.

Il codice seguente scrive 'true' nella console del browser se il clic dell'utente rientra nel triangolo definito; in caso contrario, scrive 'false'.

function initialize() {
  var mapOptions = {
    zoom: 5,
    center: new google.maps.LatLng(24.886, -70.269),
    mapTypeId: 'terrain'
  };

  var map = new google.maps.Map(document.getElementById('map'),
      mapOptions);

  var bermudaTriangle = new google.maps.Polygon({
    paths: [
      new google.maps.LatLng(25.774, -80.190),
      new google.maps.LatLng(18.466, -66.118),
      new google.maps.LatLng(32.321, -64.757)
    ]
  });

  google.maps.event.addListener(map, 'click', function(event) {
    console.log(google.maps.geometry.poly.containsLocation(event.latLng, bermudaTriangle));
  });
}

google.maps.event.addDomListener(window, 'load', initialize);

Un'altra versione di questo codice traccia un triangolo blu sulla mappa se il clic rientra nel triangolo delle Bermuda e un cerchio rosso negli altri casi:

Visualizza l'esempio

isLocationOnEdge()

isLocationOnEdge(point:LatLng, poly:Polygon|Polyline, tolerance?:number)

Per determinare se un punto si trova sopra o vicino a una polilinea, o sopra o vicino al bordo di un poligono, passa il punto, la polilinea/poligono e, facoltativamente, un valore di tolleranza in gradi a google.maps.geometry.poly.isLocationOnEdge(). La funzione restituisce true se la distanza tra il punto e il punto più vicino sulla linea o sul bordo rientra nella tolleranza specificata. Il valore predefinito di tolleranza è 10-9 gradi.

function initialize() {
  var myPosition = new google.maps.LatLng(46.0, -125.9);

  var mapOptions = {
    zoom: 5,
    center: myPosition,
    mapTypeId: 'terrain'
  };

  var map = new google.maps.Map(document.getElementById('map'),
      mapOptions);

  var cascadiaFault = new google.maps.Polyline({
    path: [
      new google.maps.LatLng(49.95, -128.1),
      new google.maps.LatLng(46.26, -126.3),
      new google.maps.LatLng(40.3, -125.4)
    ]
  });

  cascadiaFault.setMap(map);

  if (google.maps.geometry.poly.isLocationOnEdge(myPosition, cascadiaFault, 10e-1)) {
    alert("Relocate!");
  }
}

google.maps.event.addDomListener(window, 'load', initialize);