gpt4 book ai didi

javascript - 如何以编程方式触发 Mapbox GL JS Geocoder?

转载 作者:行者123 更新时间:2023-12-05 05:02:32 28 4
gpt4 key购买 nike

我正在使用 Mapbox GL JS 生成一个简单的商店查找器 map 。在其他用例中,我希望用户能够单击地理定位图标,将用户的位置传递给地理编码器并触发查询。

我卡在了函数的触发部分。我可以将地理定位结果传递给地理编码器输入,但我无法随后触发地理编码器功能。

目前,在将地理编码器输入的值设置为我的地理定位函数返回的值后,我触发了一个 keydown 事件。这应该触发地理编码操作,不是吗?

我看到文档中提到了一个 setinput 和查询方法,但我没有看到如何使用它们的可靠示例。

所以,明确地说,我的问题是,如何在设置输入值后以编程方式触发地理编码器函数?

这是我当前的代码:

let storefinder_module = (function () {
"use strict";

const DOM = {};

/* =================== private methods ================= */
function cacheDom() {}

function storeMap() {
if (!("remove" in Element.prototype)) {
Element.prototype.remove = function () {
if (this.parentNode) {
this.parentNode.removeChild(this);
}
};
}

mapboxgl.accessToken =
"removed";

/**
* Add the map to the page
*/
const map = new mapboxgl.Map({
container: "map",
style: "mapbox://styles/mapbox/light-v10",
center: [-77.034084142948, 38.909671288923],
zoom: 13,
scrollZoom: false,
});

const stores = {
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-77.034084142948, 38.909671288923],
},
properties: {
phoneFormatted: "(202) 234-7336",
phone: "2022347336",
address: "1471 P St NW",
city: "Washington DC",
country: "United States",
crossStreet: "at 15th St NW",
postalCode: "20005",
state: "D.C.",
},
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-77.049766, 38.900772],
},
properties: {
phoneFormatted: "(202) 507-8357",
phone: "2025078357",
address: "2221 I St NW",
city: "Washington DC",
country: "United States",
crossStreet: "at 22nd St NW",
postalCode: "20037",
state: "D.C.",
},
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-77.043929, 38.910525],
},
properties: {
phoneFormatted: "(202) 387-9338",
phone: "2023879338",
address: "1512 Connecticut Ave NW",
city: "Washington DC",
country: "United States",
crossStreet: "at Dupont Circle",
postalCode: "20036",
state: "D.C.",
},
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-77.0672, 38.90516896],
},
properties: {
phoneFormatted: "(202) 337-9338",
phone: "2023379338",
address: "3333 M St NW",
city: "Washington DC",
country: "United States",
crossStreet: "at 34th St NW",
postalCode: "20007",
state: "D.C.",
},
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-77.002583742142, 38.887041080933],
},
properties: {
phoneFormatted: "(202) 547-9338",
phone: "2025479338",
address: "221 Pennsylvania Ave SE",
city: "Washington DC",
country: "United States",
crossStreet: "btwn 2nd & 3rd Sts. SE",
postalCode: "20003",
state: "D.C.",
},
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-76.933492720127, 38.99225245786],
},
properties: {
address: "8204 Baltimore Ave",
city: "College Park",
country: "United States",
postalCode: "20740",
state: "MD",
},
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-77.097083330154, 38.980979],
},
properties: {
phoneFormatted: "(301) 654-7336",
phone: "3016547336",
address: "4831 Bethesda Ave",
cc: "US",
city: "Bethesda",
country: "United States",
postalCode: "20814",
state: "MD",
},
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-77.359425054188, 38.958058116661],
},
properties: {
phoneFormatted: "(571) 203-0082",
phone: "5712030082",
address: "11935 Democracy Dr",
city: "Reston",
country: "United States",
crossStreet: "btw Explorer & Library",
postalCode: "20190",
state: "VA",
},
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-77.10853099823, 38.880100922392],
},
properties: {
phoneFormatted: "(703) 522-2016",
phone: "7035222016",
address: "4075 Wilson Blvd",
city: "Arlington",
country: "United States",
crossStreet: "at N Randolph St.",
postalCode: "22203",
state: "VA",
},
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-75.28784, 40.008008],
},
properties: {
phoneFormatted: "(610) 642-9400",
phone: "6106429400",
address: "68 Coulter Ave",
city: "Ardmore",
country: "United States",
postalCode: "19003",
state: "PA",
},
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-75.20121216774, 39.954030175164],
},
properties: {
phoneFormatted: "(215) 386-1365",
phone: "2153861365",
address: "3925 Walnut St",
city: "Philadelphia",
country: "United States",
postalCode: "19104",
state: "PA",
},
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-77.043959498405, 38.903883387232],
},
properties: {
phoneFormatted: "(202) 331-3355",
phone: "2023313355",
address: "1901 L St. NW",
city: "Washington DC",
country: "United States",
crossStreet: "at 19th St",
postalCode: "20036",
state: "D.C.",
},
},
],
};

/**
* Assign a unique id to each store. You'll use this `id`
* later to associate each point on the map with a listing
* in the sidebar.
*/
stores.features.forEach(function (store, i) {
store.properties.id = i;
});

/**
* Wait until the map loads to make changes to the map.
*/
map.on("load", function (e) {
/**
* This is where your '.addLayer()' used to be, instead
* add only the source without styling a layer
*/
map.addSource("places", {
type: "geojson",
data: stores,
});

/**
* Create a new MapBoxDirections instance.
*/
//var directions = new MapboxDirections({
// accessToken: mapboxgl.accessToken,
// mapboxgl: mapboxgl,
//});

// Create a new MapboxGeocoder instance.
const geocoder = new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl,
zoom: 4,
clearAndBlurOnEsc: true,
placeholder: "Enter Your Location (Zip or Address)",
});

// Add geolocate control to the map.
const geolocate = new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true,
},
trackUserLocation: false,
});

function getAddress(lon, lat) {
let longitude = lon;
let latitude = lat;
let apiCoordtoAddress =
"https://api.mapbox.com/geocoding/v5/mapbox.places/" +
longitude +
"," +
latitude +
".json?access_token=" +
mapboxgl.accessToken;
let apiCoordtoAddressEncoded = encodeURI(apiCoordtoAddress);

$.getJSON(apiCoordtoAddressEncoded, function (data, geocoder) {
let dataAddress = data.features[0].place_name;
let $geoCoderInput = $("#geocoder .mapboxgl-ctrl-geocoder--input");

$geoCoderInput.val("20814");
$geoCoderInput.keydown();

});
}

/**
* Add all the things to the page:
* - The location listings on the side of the page
* - The search box (MapboxGeocoder) onto the map
* - The markers onto the map
*/
buildLocationList(stores);
document.getElementById("geocoder").appendChild(geocoder.onAdd(map));
addMarkers();
map.addControl(geolocate);

// Geolocate Event
geolocate.on("geolocate", function (e) {
let lon = e.coords.longitude;
let lat = e.coords.latitude;
getAddress(lon, lat);
});

/**
* Listen for when a geocoder result is returned. When one is returned:
* - Calculate distances
* - Sort stores by distance
* - Rebuild the listings
* - Adjust the map camera
* - Open a popup for the closest store
* - Highlight the listing for the closest store.
*/
geocoder.on("result", function (ev) {
/* Get the coordinate of the search result */
var searchResult = ev.result.geometry;

/**
* Calculate distances:
* For each store, use turf.distance to calculate the distance
* in miles between the searchResult and the store. Assign the
* calculated value to a property called `distance`.
*/
var options = { units: "miles" };
stores.features.forEach(function (store) {
Object.defineProperty(store.properties, "distance", {
value: turf.distance(searchResult, store.geometry, options),
writable: true,
enumerable: true,
configurable: true,
});
});

/**
* Sort stores by distance from closest to the `searchResult`
* to furthest.
*/
stores.features.sort(function (a, b) {
if (a.properties.distance > b.properties.distance) {
return 1;
}
if (a.properties.distance < b.properties.distance) {
return -1;
}
return 0; // a must be equal to b
});

/**
* Rebuild the listings:
* Remove the existing listings and build the location
* list again using the newly sorted stores.
*/
let listings = document.getElementById("listings");
while (listings.firstChild) {
listings.removeChild(listings.firstChild);
}
buildLocationList(stores);
/* Open a popup for the closest store. */
createPopUp(stores.features[0]);

/** Highlight the listing for the closest store. */
let activeListing = document.getElementById(
"listing-" + stores.features[0].properties.id
);
activeListing.classList.add("active");
});
});

/**
* Add a marker to the map for every store listing.
**/
function addMarkers() {
/* For each feature in the GeoJSON object above: */
stores.features.forEach(function (marker) {
/* Create a div element for the marker. */
const el = document.createElement("div");
/* Assign a unique `id` to the marker. */
el.id = "marker-" + marker.properties.id;
/* Assign the `marker` class to each marker for styling. */
el.className = "marker";

/**
* Create a marker using the div element
* defined above and add it to the map.
**/
new mapboxgl.Marker(el, { offset: [0, -23] })
.setLngLat(marker.geometry.coordinates)
.addTo(map);

/**
* Listen to the element and when it is clicked, do three things:
* 1. Fly to the point
* 2. Close all other popups and display popup for clicked store
* 3. Highlight listing in sidebar (and remove highlight for all other listings)
**/
el.addEventListener("click", function (e) {
flyToStore(marker);
createPopUp(marker);
var activeItem = document.getElementsByClassName("active");
e.stopPropagation();
if (activeItem[0]) {
activeItem[0].classList.remove("active");
}
let listing = document.getElementById(
"listing-" + marker.properties.id
);
listing.classList.add("active");
});
});
}

/**
* Add a listing for each store to the sidebar.
**/
function buildLocationList(data) {
data.features.forEach(function (store, i) {
/**
* Create a shortcut for `store.properties`,
* which will be used several times below.
**/
let prop = store.properties;

/* Add a new listing section to the sidebar. */
const listings = document.getElementById("listings");
const listing = listings.appendChild(document.createElement("div"));
/* Assign a unique `id` to the listing. */
listing.id = "listing-" + prop.id;
/* Assign the `item` class to each listing for styling. */
listing.className = "item";

/* Add the link to the individual listing created above. */
const link = listing.appendChild(document.createElement("a"));
link.href = "#";
link.className = "title";
link.id = "link-" + prop.id;
link.innerHTML = prop.address;

/* Add details to the individual listing. */
const details = listing.appendChild(document.createElement("div"));
details.innerHTML = prop.city;
if (prop.phone) {
details.innerHTML += " &middot; " + prop.phoneFormatted;
}
if (prop.distance) {
let roundedDistance = Math.round(prop.distance * 100) / 100;
details.innerHTML +=
"<p><strong>" + roundedDistance + " miles away</strong></p>";
}

/**
* Listen to the element and when it is clicked, do four things:
* 1. Update the `currentFeature` to the store associated with the clicked link
* 2. Fly to the point
* 3. Close all other popups and display popup for clicked store
* 4. Highlight listing in sidebar (and remove highlight for all other listings)
**/
link.addEventListener("click", function (e) {
for (var i = 0; i < data.features.length; i++) {
if (this.id === "link-" + data.features[i].properties.id) {
let clickedListing = data.features[i];
flyToStore(clickedListing);
createPopUp(clickedListing);
}
}
const activeItem = document.getElementsByClassName("active");
if (activeItem[0]) {
activeItem[0].classList.remove("active");
}
this.parentNode.classList.add("active");
});
});
}

/**
* Use Mapbox GL JS's `flyTo` to move the camera smoothly
* a given center point.
**/
function flyToStore(currentFeature) {
map.flyTo({
center: currentFeature.geometry.coordinates,
zoom: 15,
});
}

/**
* Create a Mapbox GL JS `Popup`.
**/
function createPopUp(currentFeature) {
const popUps = document.getElementsByClassName("mapboxgl-popup");
if (popUps[0]) popUps[0].remove();

var popup = new mapboxgl.Popup({
closeOnClick: false,
})
.setLngLat(currentFeature.geometry.coordinates)
.setHTML(
"<h3>Sweetgreen</h3>" +
"<h4>" +
currentFeature.properties.address +
"</h4>"
)
.addTo(map);
}

/* given a query in the form "lng, lat" or "lat, lng" returns the matching
* geographic coordinate(s) as search results in carmen geojson format,
* https://github.com/mapbox/carmen/blob/master/carmen-geojson.md
*/
let coordinatesGeocoder = function (query) {
// match anything which looks like a decimal degrees coordinate pair
let matches = query.match(
/^[ ]*(?:Lat: )?(-?\d+\.?\d*)[, ]+(?:Lng: )?(-?\d+\.?\d*)[ ]*$/i
);
if (!matches) {
return null;
}

function coordinateFeature(lng, lat) {
return {
center: [lng, lat],
geometry: {
type: "Point",
coordinates: [lng, lat],
},
place_name: "Lat: " + lat + " Lng: " + lng,
place_type: ["coordinate"],
properties: {},
type: "Feature",
};
}

let coord1 = Number(matches[1]);
let coord2 = Number(matches[2]);
const geocodes = [];

if (coord1 < -90 || coord1 > 90) {
// must be lng, lat
geocodes.push(coordinateFeature(coord1, coord2));
}

if (coord2 < -90 || coord2 > 90) {
// must be lat, lng
geocodes.push(coordinateFeature(coord2, coord1));
}

if (geocodes.length === 0) {
// else could be either lng, lat or lat, lng
geocodes.push(coordinateFeature(coord1, coord2));
geocodes.push(coordinateFeature(coord2, coord1));
}

return geocodes;
};
}

// render DOM

/* =================== public methods ================== */
function init() {
cacheDom();
storeMap();
}

/* =============== export public methods =============== */
return {
init: init,
};
})();


storefinder_module.init();

最佳答案

看起来有计划在未来的版本中对此进行更新 viewable here

与此同时,执行以下操作对我有用:

geocoder.setInput('New York')._geocode('New York');

显然,只需将“纽约”更改为您为该位置使用的任何变量即可。

您还可以执行以下操作,尽管这对我来说不太一致:

geocoder.query('New York');

关于javascript - 如何以编程方式触发 Mapbox GL JS Geocoder?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62164016/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com