Commit 6d8f59b5 authored by JOE XMG's avatar JOE XMG
Browse files

update

parent 22fcb4d1
Pipeline #6293 passed with stage
in 6 seconds
import * as L from 'leaflet';
import { getJSON } from '../util';
import {
IGeocoder,
GeocoderOptions,
GeocodingCallback,
geocodingParams,
GeocodingResult,
reverseParams
} from './api';
export interface NeutrinoOptions extends GeocoderOptions {
userId: string;
}
/**
* Implementation of the [Neutrino API](https://www.neutrinoapi.com/api/geocode-address/)
*/
export class Neutrino implements IGeocoder {
options: NeutrinoOptions = {
userId: undefined,
apiKey: undefined,
serviceUrl: 'https://neutrinoapi.com/'
};
constructor(options?: Partial<NeutrinoOptions>) {
L.Util.setOptions(this, options);
}
// https://www.neutrinoapi.com/api/geocode-address/
geocode(query: string, cb: GeocodingCallback, context?: any): void {
const params = geocodingParams(this.options, {
apiKey: this.options.apiKey,
userId: this.options.userId,
//get three words and make a dot based string
address: query.split(/\s+/).join('.')
});
getJSON(this.options.serviceUrl + 'geocode-address', params, data => {
const results: GeocodingResult[] = [];
if (data.locations) {
data.geometry = data.locations[0];
const center = L.latLng(data.geometry['latitude'], data.geometry['longitude']);
const bbox = L.latLngBounds(center, center);
results[0] = {
name: data.geometry.address,
bbox: bbox,
center: center
};
}
cb.call(context, results);
});
}
suggest(query: string, cb: GeocodingCallback, context?: any): void {
return this.geocode(query, cb, context);
}
// https://www.neutrinoapi.com/api/geocode-reverse/
reverse(location: L.LatLngLiteral, scale: number, cb: GeocodingCallback, context?: any): void {
const params = reverseParams(this.options, {
apiKey: this.options.apiKey,
userId: this.options.userId,
latitude: location.lat,
longitude: location.lng
});
getJSON(this.options.serviceUrl + 'geocode-reverse', params, data => {
const results: GeocodingResult[] = [];
if (data.status.status == 200 && data.found) {
const center = L.latLng(location.lat, location.lng);
const bbox = L.latLngBounds(center, center);
results[0] = {
name: data.address,
bbox: bbox,
center: center
};
}
cb.call(context, results);
});
}
}
/**
* [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link Neutrino}
* @param options the options
*/
export function neutrino(options?: Partial<NeutrinoOptions>) {
return new Neutrino(options);
}
import * as L from 'leaflet';
import { template, getJSON } from '../util';
import {
IGeocoder,
GeocoderOptions,
GeocodingCallback,
geocodingParams,
GeocodingResult,
reverseParams
} from './api';
export interface NominatimResult {
place_id: number;
licence: string;
osm_type: string;
osm_id: number;
boundingbox: string[];
lat: string;
lon: string;
display_name: string;
class: string;
type: string;
importance: number;
icon?: string;
address: NominatimAddress;
}
export interface NominatimAddress {
building?: string;
city_district?: string;
city?: string;
country_code?: string;
country?: string;
county?: string;
hamlet?: string;
house_number?: string;
neighbourhood?: string;
postcode?: string;
road?: string;
state_district?: string;
state?: string;
suburb?: string;
village?: string;
}
export interface NominatimOptions extends GeocoderOptions {
/**
* Additional URL parameters (strings) that will be added to geocoding requests; can be used to restrict results to a specific country for example, by providing the [`countrycodes`](https://wiki.openstreetmap.org/wiki/Nominatim#Parameters) parameter to Nominatim
*/
geocodingQueryParams?: Record<string, unknown>;
/**
* A function that takes an GeocodingResult as argument and returns an HTML formatted string that represents the result. Default function breaks up address in parts from most to least specific, in attempt to increase readability compared to Nominatim's naming
*/
htmlTemplate: (r: NominatimResult) => string;
}
/**
* Implementation of the [Nominatim](https://wiki.openstreetmap.org/wiki/Nominatim) geocoder.
*
* This is the default geocoding service used by the control, unless otherwise specified in the options.
*
* Unless using your own Nominatim installation, please refer to the [Nominatim usage policy](https://operations.osmfoundation.org/policies/nominatim/).
*/
export class Nominatim implements IGeocoder {
options: NominatimOptions = {
serviceUrl: 'https://nominatim.openstreetmap.org/',
htmlTemplate: function(r: NominatimResult) {
const address = r.address;
let className: string;
const parts = [];
if (address.road || address.building) {
parts.push('{building} {road} {house_number}');
}
if (address.city || (address as any).town || address.village || address.hamlet) {
className = parts.length > 0 ? 'leaflet-control-geocoder-address-detail' : '';
parts.push(
'<span class="' + className + '">{postcode} {city} {town} {village} {hamlet}</span>'
);
}
if (address.state || address.country) {
className = parts.length > 0 ? 'leaflet-control-geocoder-address-context' : '';
parts.push('<span class="' + className + '">{state} {country}</span>');
}
return template(parts.join('<br/>'), address);
}
};
constructor(options?: Partial<NominatimOptions>) {
L.Util.setOptions(this, options || {});
}
geocode(query: string, cb: GeocodingCallback, context?: any) {
const params = geocodingParams(this.options, {
q: query,
limit: 5,
format: 'json',
addressdetails: 1
});
getJSON(this.options.serviceUrl + 'search', params, data => {
const results: GeocodingResult[] = [];
for (let i = data.length - 1; i >= 0; i--) {
const bbox = data[i].boundingbox;
for (let j = 0; j < 4; j++) bbox[j] = +bbox[j];
results[i] = {
icon: data[i].icon,
name: data[i].display_name,
html: this.options.htmlTemplate ? this.options.htmlTemplate(data[i]) : undefined,
bbox: L.latLngBounds([bbox[0], bbox[2]], [bbox[1], bbox[3]]),
center: L.latLng(data[i].lat, data[i].lon),
properties: data[i]
};
}
cb.call(context, results);
});
}
reverse(location: L.LatLngLiteral, scale: number, cb: GeocodingCallback, context?: any) {
const params = reverseParams(this.options, {
lat: location.lat,
lon: location.lng,
zoom: Math.round(Math.log(scale / 256) / Math.log(2)),
addressdetails: 1,
format: 'json'
});
getJSON(this.options.serviceUrl + 'reverse', params, data => {
const result: GeocodingResult[] = [];
if (data && data.lat && data.lon) {
const center = L.latLng(data.lat, data.lon);
const bbox = L.latLngBounds(center, center);
result.push({
name: data.display_name,
html: this.options.htmlTemplate ? this.options.htmlTemplate(data) : undefined,
center: center,
bbox: bbox,
properties: data
});
}
cb.call(context, result);
});
}
}
/**
* [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link Nominatim}
* @param options the options
*/
export function nominatim(options?: Partial<NominatimOptions>) {
return new Nominatim(options);
}
import * as L from 'leaflet';
import { IGeocoder, GeocodingCallback, GeocodingResult } from './api';
export interface OpenLocationCodeOptions {
OpenLocationCode: OpenLocationCodeApi;
codeLength?: number;
}
export interface OpenLocationCodeApi {
encode(latitude: number, longitude: number, codeLength?: number): string;
decode(code: string): CodeArea;
}
export interface CodeArea {
latitudeLo: number;
longitudeLo: number;
latitudeHi: number;
longitudeHi: number;
latitudeCenter: number;
longitudeCenter: number;
codeLength: number;
}
/**
* Implementation of the [Plus codes](https://plus.codes/) (formerly OpenLocationCode) (requires [open-location-code](https://www.npmjs.com/package/open-location-code))
*/
export class OpenLocationCode implements IGeocoder {
options: OpenLocationCodeOptions;
constructor(options?: Partial<OpenLocationCodeOptions>) {
L.Util.setOptions(this, options);
}
geocode(query: string, cb: GeocodingCallback, context?: any) {
try {
const decoded = this.options.OpenLocationCode.decode(query);
const result: GeocodingResult = {
name: query,
center: L.latLng(decoded.latitudeCenter, decoded.longitudeCenter),
bbox: L.latLngBounds(
L.latLng(decoded.latitudeLo, decoded.longitudeLo),
L.latLng(decoded.latitudeHi, decoded.longitudeHi)
)
};
cb.call(context, [result]);
} catch (e) {
console.warn(e); // eslint-disable-line no-console
cb.call(context, []);
}
}
reverse(location: L.LatLngLiteral, scale: number, cb: GeocodingCallback, context?: any) {
try {
const code = this.options.OpenLocationCode.encode(
location.lat,
location.lng,
this.options.codeLength
);
const result = {
name: code,
center: L.latLng(location.lat, location.lng),
bbox: L.latLngBounds(
L.latLng(location.lat, location.lng),
L.latLng(location.lat, location.lng)
)
};
cb.call(context, [result]);
} catch (e) {
console.warn(e); // eslint-disable-line no-console
cb.call(context, []);
}
}
}
/**
* [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link OpenLocationCode}
* @param options the options
*/
export function openLocationCode(options?: Partial<OpenLocationCodeOptions>) {
return new OpenLocationCode(options);
}
import * as L from 'leaflet';
import { getJSON } from '../util';
import {
IGeocoder,
GeocoderOptions,
GeocodingCallback,
geocodingParams,
GeocodingResult,
reverseParams
} from './api';
export interface OpenCageOptions extends GeocoderOptions {}
/**
* Implementation of the [OpenCage Data API](https://opencagedata.com/)
*/
export class OpenCage implements IGeocoder {
options: OpenCageOptions = {
serviceUrl: 'https://api.opencagedata.com/geocode/v1/json'
};
constructor(options?: Partial<OpenCageOptions>) {
L.Util.setOptions(this, options);
}
geocode(query: string, cb: GeocodingCallback, context?: any): void {
const params = geocodingParams(this.options, {
key: this.options.apiKey,
q: query
});
getJSON(this.options.serviceUrl, params, data => {
const results: GeocodingResult[] = [];
if (data.results && data.results.length) {
for (let i = 0; i < data.results.length; i++) {
const loc = data.results[i];
const center = L.latLng(loc.geometry);
let bbox: L.LatLngBounds;
if (loc.annotations && loc.annotations.bounds) {
bbox = L.latLngBounds(
L.latLng(loc.annotations.bounds.northeast),
L.latLng(loc.annotations.bounds.southwest)
);
} else {
bbox = L.latLngBounds(center, center);
}
results.push({
name: loc.formatted,
bbox: bbox,
center: center
});
}
}
cb.call(context, results);
});
}
suggest(query: string, cb: GeocodingCallback, context?: any): void {
return this.geocode(query, cb, context);
}
reverse(location: L.LatLngLiteral, scale: number, cb: GeocodingCallback, context?: any): void {
const params = reverseParams(this.options, {
key: this.options.apiKey,
q: [location.lat, location.lng].join(',')
});
getJSON(this.options.serviceUrl, params, data => {
const results: GeocodingResult[] = [];
if (data.results && data.results.length) {
for (let i = 0; i < data.results.length; i++) {
const loc = data.results[i];
const center = L.latLng(loc.geometry);
let bbox: L.LatLngBounds;
if (loc.annotations && loc.annotations.bounds) {
bbox = L.latLngBounds(
L.latLng(loc.annotations.bounds.northeast),
L.latLng(loc.annotations.bounds.southwest)
);
} else {
bbox = L.latLngBounds(center, center);
}
results.push({
name: loc.formatted,
bbox: bbox,
center: center
});
}
}
cb.call(context, results);
});
}
}
export function opencage(options?: Partial<OpenCageOptions>) {
return new OpenCage(options);
}
import * as L from 'leaflet';
import { getJSON } from '../util';
import {
IGeocoder,
GeocoderOptions,
GeocodingCallback,
geocodingParams,
GeocodingResult,
reverseParams
} from './api';
export interface PeliasOptions extends GeocoderOptions {}
/**
* Implementation of the [Pelias](https://pelias.io/), [geocode.earth](https://geocode.earth/) geocoder (formerly Mapzen Search)
*/
export class Pelias implements IGeocoder {
options: PeliasOptions = {
serviceUrl: 'https://api.geocode.earth/v1'
};
private _lastSuggest = 0;
constructor(options?: Partial<PeliasOptions>) {
L.Util.setOptions(this, options);
}
geocode(query: string, cb: GeocodingCallback, context?: any): void {
const params = geocodingParams(this.options, {
api_key: this.options.apiKey,
text: query
});
getJSON(this.options.serviceUrl + '/search', params, data => {
cb.call(context, this._parseResults(data, 'bbox'));
});
}
suggest(query: string, cb: GeocodingCallback, context?: any): void {
const params = geocodingParams(this.options, {
api_key: this.options.apiKey,
text: query
});
getJSON(this.options.serviceUrl + '/autocomplete', params, data => {
if (data.geocoding.timestamp > this._lastSuggest) {
this._lastSuggest = data.geocoding.timestamp;
cb.call(context, this._parseResults(data, 'bbox'));
}
});
}
reverse(location: L.LatLngLiteral, scale: number, cb: GeocodingCallback, context?: any): void {
const params = reverseParams(this.options, {
api_key: this.options.apiKey,
'point.lat': location.lat,
'point.lon': location.lng
});
getJSON(this.options.serviceUrl + '/reverse', params, data => {
cb.call(context, this._parseResults(data, 'bounds'));
});
}
_parseResults(data, bboxname) {
const results: GeocodingResult[] = [];
L.geoJSON(data, {
pointToLayer: function(feature, latlng) {
return L.circleMarker(latlng);
},
onEachFeature: function(feature, layer: any) {
const result = {} as GeocodingResult;
let bbox;
let center;
if (layer.getBounds) {
bbox = layer.getBounds();
center = bbox.getCenter();
} else if (layer.feature.bbox) {
center = layer.getLatLng();
bbox = L.latLngBounds(
L.GeoJSON.coordsToLatLng(layer.feature.bbox.slice(0, 2)),
L.GeoJSON.coordsToLatLng(layer.feature.bbox.slice(2, 4))
);
} else {
center = layer.getLatLng();
bbox = L.latLngBounds(center, center);
}
result.name = layer.feature.properties.label;
result.center = center;
result[bboxname] = bbox;
result.properties = layer.feature.properties;
results.push(result);
}
});
return results;
}
}
/**
* [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link Pelias}
* @param options the options
*/
export function pelias(options?: Partial<PeliasOptions>) {
return new Pelias(options);
}
export const GeocodeEarth = Pelias;
export const geocodeEarth = pelias;
/**
* r.i.p.
* @deprecated
*/
export const Mapzen = Pelias;
/**
* r.i.p.
* @deprecated
*/
export const mapzen = pelias;
/**
* Implementation of the [Openrouteservice](https://openrouteservice.org/dev/#/api-docs/geocode) geocoder
*/
export class Openrouteservice extends Pelias {
constructor(options?: Partial<PeliasOptions>) {
super(
L.Util.extend(
{
serviceUrl: 'https://api.openrouteservice.org/geocode'
},
options
)
);
}
}
/**
* [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link Openrouteservice}
* @param options the options
*/
export function openrouteservice(options?: Partial<PeliasOptions>) {
return new Openrouteservice(options);
}
import * as L from 'leaflet';
import { getJSON } from '../util';
import {
IGeocoder,
GeocoderOptions,
GeocodingCallback,
geocodingParams,
GeocodingResult,
reverseParams
} from './api';
export interface PhotonOptions extends GeocoderOptions {
reverseUrl: string;
nameProperties: string[];
htmlTemplate?: (r: any) => string;
}
/**
* Implementation of the [Photon](http://photon.komoot.de/) geocoder
*/
export class Photon implements IGeocoder {
options: PhotonOptions = {
serviceUrl: 'https://photon.komoot.io/api/',
reverseUrl: 'https://photon.komoot.io/reverse/',
nameProperties: ['name', 'street', 'suburb', 'hamlet', 'town', 'city', 'state', 'country']
};
constructor(options?: Partial<PhotonOptions>) {
L.Util.setOptions(this, options);
}
geocode(query: string, cb: GeocodingCallback, context?: any): void {
const params = geocodingParams(this.options, { q: query });
getJSON(
this.options.serviceUrl,
params,
L.Util.bind(function(data) {
cb.call(context, this._decodeFeatures(data));
}, this)
);
}
suggest(query: string, cb: GeocodingCallback, context?: any): void {
return this.geocode(query, cb, context);
}
reverse(latLng: L.LatLngLiteral, scale: number, cb: GeocodingCallback, context?: any): void {
const params = reverseParams(this.options, {
lat: latLng.lat,
lon: latLng.lng
});
getJSON(
this.options.reverseUrl,
params,
L.Util.bind(function(data) {
cb.call(context, this._decodeFeatures(data));
}, this)
);
}
_decodeFeatures(data: GeoJSON.FeatureCollection<GeoJSON.Point>) {
const results: GeocodingResult[] = [];
if (data && data.features) {
for (let i = 0; i < data.features.length; i++) {
const f = data.features[i];
const c = f.geometry.coordinates;
const center = L.latLng(c[1], c[0]);
const extent = f.properties.extent;
const bbox = extent
? L.latLngBounds([extent[1], extent[0]], [extent[3], extent[2]])
: L.latLngBounds(center, center);
results.push({
name: this._decodeFeatureName(f),
html: this.options.htmlTemplate ? this.options.htmlTemplate(f) : undefined,
center: center,
bbox: bbox,
properties: f.properties
});
}
}
return results;
}
_decodeFeatureName(f: GeoJSON.Feature) {
return (this.options.nameProperties || [])
.map(p => {
return f.properties[p];
})
.filter(v => {
return !!v;
})
.join(', ');
}
}
/**
* [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link Photon}
* @param options the options
*/
export function photon(options?: Partial<PhotonOptions>) {
return new Photon(options);
}
import * as L from 'leaflet';
import { getJSON } from '../util';
import {
IGeocoder,
GeocoderOptions,
GeocodingCallback,
geocodingParams,
GeocodingResult,
reverseParams
} from './api';
export interface What3WordsOptions extends GeocoderOptions {}
/**
* Implementation of the What3Words service
*/
export class What3Words implements IGeocoder {
options: What3WordsOptions = {
serviceUrl: 'https://api.what3words.com/v2/'
};
constructor(options: Partial<What3WordsOptions>) {
L.Util.setOptions(this, options);
}
geocode(query: string, cb: GeocodingCallback, context?: any): void {
//get three words and make a dot based string
getJSON(
this.options.serviceUrl + 'forward',
geocodingParams(this.options, {
key: this.options.apiKey,
addr: query.split(/\s+/).join('.')
}),
data => {
const results: GeocodingResult[] = [];
if (data.geometry) {
const latLng = L.latLng(data.geometry['lat'], data.geometry['lng']);
const latLngBounds = L.latLngBounds(latLng, latLng);
results[0] = {
name: data.words,
bbox: latLngBounds,
center: latLng
};
}
cb.call(context, results);
}
);
}
suggest(query: string, cb: GeocodingCallback, context?: any): void {
return this.geocode(query, cb, context);
}
reverse(location: L.LatLngLiteral, scale: number, cb: GeocodingCallback, context?: any): void {
getJSON(
this.options.serviceUrl + 'reverse',
reverseParams(this.options, {
key: this.options.apiKey,
coords: [location.lat, location.lng].join(',')
}),
data => {
const results: GeocodingResult[] = [];
if (data.status.status == 200) {
const center = L.latLng(data.geometry['lat'], data.geometry['lng']);
const bbox = L.latLngBounds(center, center);
results[0] = {
name: data.words,
bbox: bbox,
center: center
};
}
cb.call(context, results);
}
);
}
}
/**
* [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link What3Words}
* @param options the options
*/
export function what3words(options: Partial<What3WordsOptions>) {
return new What3Words(options);
}
/* @preserve
* Leaflet Control Geocoder
* https://github.com/perliedman/leaflet-control-geocoder
*
* Copyright (c) 2012 sa3m (https://github.com/sa3m)
* Copyright (c) 2018 Per Liedman
* All rights reserved.
*/
import * as L from 'leaflet';
import { GeocoderControl as Geocoder, geocoder } from './control';
import * as geocoders from './geocoders/index';
L.Util.extend(Geocoder, geocoders);
export default Geocoder;
export { Geocoder, geocoder, geocoders };
L.Util.extend(L.Control, {
Geocoder: Geocoder,
geocoder: geocoder
});
import * as L from 'leaflet';
/**
* @internal
*/
let lastCallbackId = 0;
// Adapted from handlebars.js
// https://github.com/wycats/handlebars.js/
/**
* @internal
*/
const badChars = /[&<>"'`]/g;
/**
* @internal
*/
const possible = /[&<>"'`]/;
/**
* @internal
*/
const escape: Record<string, string> = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;',
'`': '&#x60;'
};
/**
* @internal
*/
function escapeChar(chr: string) {
return escape[chr];
}
/**
* @internal
*/
export function htmlEscape(string?: string): string {
if (string == null) {
return '';
} else if (!string) {
return string + '';
}
// Force a string conversion as this will be done by the append regardless and
// the regex test will do this transparently behind the scenes, causing issues if
// an object's to string has escaped characters in it.
string = '' + string;
if (!possible.test(string)) {
return string;
}
return string.replace(badChars, escapeChar);
}
/**
* @internal
*/
export function jsonp(
url: string,
params: Record<string, any>,
callback: (message: any) => void,
context: any,
jsonpParam?: string
) {
const callbackId = '_l_geocoder_' + lastCallbackId++;
params[jsonpParam || 'callback'] = callbackId;
(window as any)[callbackId] = L.Util.bind(callback, context);
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = url + getParamString(params);
script.id = callbackId;
document.getElementsByTagName('head')[0].appendChild(script);
}
/**
* @internal
*/
export function getJSON(
url: string,
params: Record<string, unknown>,
callback: (message: any) => void
): void {
const xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState !== 4) {
return;
}
let message;
if (xmlHttp.status !== 200 && xmlHttp.status !== 304) {
message = '';
} else if (typeof xmlHttp.response === 'string') {
// IE doesn't parse JSON responses even with responseType: 'json'.
try {
message = JSON.parse(xmlHttp.response);
} catch (e) {
// Not a JSON response
message = xmlHttp.response;
}
} else {
message = xmlHttp.response;
}
callback(message);
};
xmlHttp.open('GET', url + getParamString(params), true);
xmlHttp.responseType = 'json';
xmlHttp.setRequestHeader('Accept', 'application/json');
xmlHttp.send(null);
}
/**
* @internal
*/
export function template(str: string, data: Record<string, any>): string {
return str.replace(/\{ *([\w_]+) *\}/g, (str, key) => {
let value = data[key];
if (value === undefined) {
value = '';
} else if (typeof value === 'function') {
value = value(data);
}
return htmlEscape(value);
});
}
/**
* @internal
*/
export function getParamString(
obj: Record<string, unknown | unknown[]>,
existingUrl?: string,
uppercase?: boolean
): string {
const params = [];
for (const i in obj) {
const key = encodeURIComponent(uppercase ? i.toUpperCase() : i);
const value = obj[i];
if (!Array.isArray(value)) {
params.push(key + '=' + encodeURIComponent(String(value)));
} else {
for (let j = 0; j < value.length; j++) {
params.push(key + '=' + encodeURIComponent(value[j]));
}
}
}
return (!existingUrl || existingUrl.indexOf('?') === -1 ? '?' : '&') + params.join('&');
}
{
"compilerOptions": {
"target": "es5",
"module": "es2015",
"esModuleInterop": true,
"strict": false
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment