UNPKG

terriajs

Version:

Geospatial data visualization platform.

217 lines 9.71 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import i18next from "i18next"; import { makeObservable, override, runInAction } from "mobx"; import Rectangle from "terriajs-cesium/Source/Core/Rectangle"; import Resource from "terriajs-cesium/Source/Core/Resource"; import { Category, SearchAction } from "../../Core/AnalyticEvents/analyticEvents"; import isDefined from "../../Core/isDefined"; import loadJson from "../../Core/loadJson"; import { applyTranslationIfExists } from "../../Language/languageHelpers"; import prettifyCoordinates from "../../Map/Vector/prettifyCoordinates"; import LocationSearchProviderMixin, { getMapCenter } from "../../ModelMixins/SearchProviders/LocationSearchProviderMixin"; import MapboxSearchProviderTraits from "../../Traits/SearchProviders/MapboxSearchProviderTraits"; import CommonStrata from "../Definition/CommonStrata"; import CreateModel from "../Definition/CreateModel"; import SearchResult from "./SearchResult"; var MapboxGeocodeDirection; (function (MapboxGeocodeDirection) { MapboxGeocodeDirection["Forward"] = "forward"; MapboxGeocodeDirection["Reverse"] = "reverse"; })(MapboxGeocodeDirection || (MapboxGeocodeDirection = {})); export default class MapboxSearchProvider extends LocationSearchProviderMixin(CreateModel(MapboxSearchProviderTraits)) { static type = "mapbox-search-provider"; get type() { return MapboxSearchProvider.type; } constructor(uniqueId, terria) { super(uniqueId, terria); makeObservable(this); } showWarning() { if (!this.accessToken || this.accessToken === "") { console.warn(`The ${applyTranslationIfExists(this.name, i18next)}(${this.type}) geocoder will always return no results because a Mapbox token has not been provided. Please get a token from mapbox.com and add it to parameters.mapboxSearchProviderAccessToken in config.json.`); } } logEvent(searchText) { this.terria.analytics?.logEvent(Category.search, SearchAction.mapbox, searchText); } doSearch(searchText, searchResults) { searchResults.results.length = 0; searchResults.message = undefined; const isCoordinate = RegExp(/^-?([0-9]{1,2}|1[0-7][0-9]|180)(\.[0-9]{1,17})$/); const isCSCoordinatePair = RegExp(/([+-]?\d+\.?\d+)\s*,\s*([+-]?\d+\.?\d+)/); let searchDirection = isCSCoordinatePair.test(searchText) ? MapboxGeocodeDirection.Reverse : MapboxGeocodeDirection.Forward; let queryParams = { access_token: this.accessToken, autocomplete: this.partialMatch, language: this.language }; //check if geocoder should be reverse and set up. if (searchDirection === MapboxGeocodeDirection.Reverse) { let lonLat = searchText.split(/\s+/).join("").split(","); if (lonLat.length === 2 && isCoordinate.test(lonLat[0]) && isCoordinate.test(lonLat[1])) { // need to reverse the coord order if true. if (this.latLonSearchOrder) { lonLat = lonLat.reverse(); } const [lonf, latf] = lonLat.map(parseFloat); if (this.showCoordinatesInReverseGeocodeResult) { const prettyCoords = prettifyCoordinates(lonf, latf); searchResults.results.push(new SearchResult({ name: `${prettyCoords.latitude}, ${prettyCoords.longitude}`, clickAction: createZoomToFunction(this, { geometry: { coordinates: [lonf, latf] }, properties: {} }), location: { longitude: lonf, latitude: latf } })); } queryParams = { ...queryParams, ...{ longitude: lonLat[0], latitude: lonLat[1], limit: 1 //limit for reverse geocoder is per type } }; } else { //if lonLat fails to parse, then assume is forward geocode searchDirection = MapboxGeocodeDirection.Forward; } } const searchQuery = new Resource({ url: new URL(searchDirection, this.url).toString(), queryParameters: queryParams }); if (searchDirection === MapboxGeocodeDirection.Forward) { searchQuery.appendQueryParameters({ q: searchText, limit: this.limit }); } if (searchDirection === MapboxGeocodeDirection.Forward && this.mapCenter) { const mapCenter = getMapCenter(this.terria); searchQuery.appendQueryParameters({ proximity: `${mapCenter.longitude}, ${mapCenter.latitude}` }); } if (searchDirection === MapboxGeocodeDirection.Forward && this.terria.searchBarModel.boundingBoxLimit) { const bbox = this.terria.searchBarModel.boundingBoxLimit; if (isDefined(bbox.west) && isDefined(bbox.north) && isDefined(bbox.east) && isDefined(bbox.south)) { searchQuery.appendQueryParameters({ bbox: [bbox.west, bbox.north, bbox.east, bbox.south].join(",") }); } } if (this.country) { searchQuery.appendQueryParameters({ country: this.country }); } if (this.types) { searchQuery.appendQueryParameters({ types: this.types }); } if (this.worldview) { searchQuery.appendQueryParameters({ worldview: this.worldview }); } const promise = loadJson(searchQuery); return promise .then((result) => { if (searchResults.isCanceled) { // A new search has superseded this one, so ignore the result. return; } if ((result.features.length === 0 && searchDirection === MapboxGeocodeDirection.Forward) || //in the case where coordinate result is true, list is //not empty. (result.features.length === 0 && searchDirection === MapboxGeocodeDirection.Reverse && this.showCoordinatesInReverseGeocodeResult === false)) { searchResults.message = { content: "translate#viewModels.searchNoLocations" }; return; } const locations = result.features .filter((feat) => feat.properties && feat.geometry && feat.properties.full_address) .map((feat) => { return new SearchResult({ name: feat.properties.full_address, clickAction: createZoomToFunction(this, feat), location: { latitude: feat.geometry.coordinates[1], longitude: feat.geometry.coordinates[0] } }); }); runInAction(() => { searchResults.results.push(...locations); }); if (searchResults.results.length === 0) { searchResults.message = { content: "translate#viewModels.searchNoLocations" }; } const attribution = result.attribution; if (attribution) { runInAction(() => { this.setTrait(CommonStrata.underride, "attributions", [ attribution ]); }); } }) .catch(() => { if (searchResults.isCanceled) { // A new search has superseded this one, so ignore the result. return; } searchResults.message = { content: "translate#viewModels.searchErrorOccurred" }; }); } } __decorate([ override ], MapboxSearchProvider.prototype, "showWarning", null); function createZoomToFunction(model, resource) { // mapbox doesn't return a bbox for street names etc, so we // need to create it ourselves. const [west, north, east, south] = resource.properties.bbox ?? [ resource.geometry.coordinates[0] - 0.01, resource.geometry.coordinates[1] - 0.01, resource.geometry.coordinates[0] + 0.01, resource.geometry.coordinates[1] + 0.01 ]; const rectangle = Rectangle.fromDegrees(west, south, east, north); return function () { const terria = model.terria; terria.currentViewer.zoomTo(rectangle, model.flightDurationSeconds); }; } //# sourceMappingURL=MapboxSearchProvider.js.map