- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 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 += " · " + 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/
我正在使用 Visual Studio 2010。 我正在尝试在 OpenGL 中编写简单的 Camera 类。 我需要在 Camera.h 中包含 gl/gl.h gl/gl.h 已经包含在 mai
这个问题适用于了解 MapBox GL JS 内部结构的人。 我正在使用 MapBox GL JS 渲染多达 40,000 个多边形的地理 map ,每个多边形的颜色都基于该多边形的“所有者”。每个所
我想知道3D建筑物的“填充颜色”是否可以根据某些事件动态更改,例如将鼠标悬停在建筑物上时的mouseMoveEvent,突出显示3D建筑物。 最佳答案 试试这个 map.on('load', func
我正在使用 mapbox-gl 并从 osm2vectortiles.org 下载矢量切片 我想让 map 仅在已知多边形内可见,但找不到任何方法来实现这一点。 我可以想象几种解决这个问题的方法,但每
在探索javascript的过程中,我遇到了一个很莫名其妙的问题。序言是:我将不同 mime 类型的图像(主要是 pngs/jpgs)转换为具有 ImageBitmap 接口(interface)的位
我一直在使用行程图层可视化行程数据,并且尝试在每条行程线的开头放置一个图标。是否可以让多个图标随时间改变位置、出现和消失? Example of what I'm trying to do (red
我有一个 map 应用程序,它使用 Mapbox.com 来提供英国邮政编码边界的矢量切片。边界文件很大,不适合使用 TopoJSON 之类的工具进行下载。这很好用。 我还使用数据驱动的样式来格式化
将鼠标悬停在一个 3D 建筑上时,如何突出显示它?像 OSM 建筑物突出显示功能。 mapbox street v7 建筑图层特征属性好像很少,只包括: 拉伸(stretch) 高度 最小高度 类型
有没有办法隐藏/删除或禁用控件,例如 mapbox-gl-draw 中的控件? 我添加绘制控件如下 draw = mapboxgl.Draw({ drawing: true,
这可能非常简单,但我找不到如何在 deck.gl 的标签下方添加新层。它在底层使用 Mapbox GL JS。对于 mapbox gl,解释为 here . 我还在他们的文档中搜索了 z-index
我正在寻找一种方法,允许我像 Mapbox JS 一样为我的 map 创建一个简单的自定义标记。 深入浏览了网络,似乎没有明显或非常直接的方法来实现这一目标。我猜这是一个被错过的功能。 尝试过使用Ma
接下来的教程向我展示了以下代码: ... void update() { glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLES);
我正在寻找一种方法,允许我像 Mapbox JS 一样为我的 map 创建一个简单的自定义标记。 深入浏览了网络,似乎没有明显或非常直接的方法来实现这一目标。我猜这是一个被错过的功能。 尝试过使用Ma
我想在交互式 map 上显示一个圆圈的轮廓(无填充)但是,mapbox-gl-js 中的绘制选项似乎仅限于填充。 https://www.mapbox.com/mapbox-gl-style-spec
我在 kepler.gl 中工作并从数据库加载数据。如果数据库更新,我希望能够动态更新数据集。有没有办法向数据集添加一行并更新 map ? 我已经尝试删除数据集(使用 removeDataset)并将
如何在 mapbox-gl 中为图层文本字段添加背景颜色 .. 或者如何完成以便文本字段上有背景框 map.addLayer({ "id": "markers", "type": "s
我正在尝试使用 mapbox-gl 创建等值线图。在示例等值线 map 中,看起来他们根据要素的属性设置了要素的油漆填充颜色。有没有办法通过访问 map 来设置颜色? 即。我在称为 id 的功能属性中
我想根据最近的草皮更改 map 点击时的图标大小。我如何做到这一点? nearestBuilding.properties['icon-size'] = 0.2; 不起作用。 var retail =
我正在尝试在 MapBox GL JS 中聚类自定义标记,但我不知道如何将自定义标记图像从 url 获取到符号层?它要么不起作用,要么根本没有标记出现。它是如何完成的?我需要知道如何使用带有符号层的
寻找一种使用 Mapbox GL JS 获取 map 中心当前坐标的方法,就像在 Mapbox Studio 上一样(见下文) Mapbox Studio Screenshot 谢谢 最佳答案 Map
我是一名优秀的程序员,十分优秀!