gpt4 book ai didi

javascript - 是否可以使用 “HERE Maps API for JavaScript” 以可接受的性能渲染邮政编码边框?

转载 作者:行者123 更新时间:2023-11-28 03:17:02 26 4
gpt4 key购买 nike

我想在全国范围内呈现大约 4500 个邮政编码。每个邮政编码多边形都足够精确并且有很多点(顶点)。我需要能够单独与每个邮政编码交互(在鼠标悬停时突出显示它)。

就我当前的实现而言,性能还不够。渲染/重新渲染很慢(渲染按部分执行)以及突出显示(通过 setStyle() 更改 fillColor)。

如何实现:

  • 所有数据均以 GeoJSON 形式存储并传递到 HERE map 中。为 4500 个邮政编码中的每一个提供单独的 GeoJSON;
  • 使用H.data.geojson.Reader();
  • H.map.Group 已创建,所有多边形均添加到该组中;

如何优化:

  • 所有多边形都尽可能地简化(实际上我想避免这种情况,但看起来这是不可能的)
  • 仅渲染与 map View 边界框相交的多边形。每个渲染有 70 - 180 个多边形。我不渲染所有 4500 个多边形。当我在“mapviewchangeend”上平移 map 时,我使用 group.removeAll() 从组中删除所有对象,并根据更改的边界框添加新对象。

这是如此数量的多边形渲染性能的预期结果还是我的逻辑出了问题?也许还有另一种方法可以以可接受的性能呈现邮政编码?

代码:

class GCM {
private m_areasDataCache: Map<number, object[]> = new Map();
private m_map: H.Map;
private m_currentDataLevel?: number;
private m_areasGroup: H.map.Group;
private m_shallRenderAreas = true;
private m_preloadingStatus = 0; // 0 - Preloading hasn't been happen yet
private m_servicesURL = "http://localhost:3000/";
private m_lastActiveArea: H.map.Polygon;
private m_normalAreaStyle = {
fillColor: 'rgba(255, 255, 255, 0.3)',
strokeColor: 'rgba(0, 0, 0, 1)',
lineWidth: 1
};
private m_activeAreaStyle = {
fillColor: 'rgba(255, 0, 0, 1)',
strokeColor: 'rgba(0, 0, 0, 1)',
lineWidth: 1
};

startApp() {
this.setupMap();
}

async renderAreas() {
if (this.m_shallRenderAreas === false) {
return;
}

const dataLevel = this.getDataLevel(this.m_map.getZoom());
if (
// do not render areas again if they already rendered
this.m_currentDataLevel === dataLevel
// in case of zip code level perform rendering in order to take into account new bounding box
&& dataLevel !== 4
) {
return;
}

this.m_currentDataLevel = dataLevel;

let areas = [];
if (!this.m_areasDataCache.has(dataLevel)) {
const areasData = await this.readData(this.m_servicesURL + "?level=" + dataLevel);
areas = JSON.parse(areasData);

this.m_areasDataCache.set(dataLevel, areas);
} else {
areas = this.m_areasDataCache.get(dataLevel);
}

// cleanup the layer by removing objects from the group
const group = this.getAreasGroup();
group.removeAll();

for (const area of areas) {
if (this.isInBoundingBox(area.bounding_box)) {
this.renderAreasPolygons(area);
}
}

// it's time to pre-load zip codes polygones
// TODO: it is possible to preload also other levels if needed
if (!this.m_areasDataCache.has(4) && this.m_preloadingStatus === 0) {
this.m_preloadingStatus = 1; // 1 - Preloading started
this.preloadData().then(() => {
this.m_preloadingStatus = 2; // 2 - Preloading finished
});
}
}

/**
* Some data, such as Zip Codes polygons can be preloaded when the application is in idle state
* in order to be ready to render it as soon as possible when it will be required.
*/
private async preloadData() {
const dataLevel = 4;
const areasData = await this.readData(this.m_servicesURL + "?level=" + dataLevel);
const areas = JSON.parse(areasData);
this.m_areasDataCache.set(dataLevel, areas);
}

private isInBoundingBox(areaBoundingBox: any): boolean {
if (areaBoundingBox === null) {
return true;
}

// json bounding box
const areaRect = new H.geo.Rect(
areaBoundingBox.TopLeft.Latitude,
areaBoundingBox.TopLeft.Longitude,
areaBoundingBox.BottomRight.Latitude,
areaBoundingBox.BottomRight.Longitude
);

const mapViewBoundingBox = (this.m_map.getViewModel() as any).getLookAtData().bounds.getBoundingBox();
const isInBoundingBox = mapViewBoundingBox.intersects(areaRect);

return isInBoundingBox;
}

private getDataLevel(zoomLevel: number): number {
let dataLevel = 0; // Country

if (zoomLevel > 5 && zoomLevel <= 6) {
dataLevel = 1; // NUTS 1
} else if (zoomLevel > 6 && zoomLevel <= 7) {
dataLevel = 2; // NUTS 2
} else if (zoomLevel > 7 && zoomLevel <= 10) {
dataLevel = 3; // NUTS 3
} else if (zoomLevel > 10) {
dataLevel = 4; // ZIP
}

return dataLevel;
}

private areaStyle(mapObjects: H.map.Object[]) {
for (const mapObject of mapObjects) {
if (mapObject instanceof H.map.Polygon) {
mapObject.setStyle(this.m_normalAreaStyle);
}
}
}

private renderAreasPolygons(area: any) {
var reader = new (H.data as any).geojson.Reader(undefined, {
// This function is called each time parser detects a new map object
style: (mapObject: H.map.Polygon | H.map.Group) => {
if (mapObject instanceof H.map.Polygon) {
this.areaStyle([mapObject]);
} else if (mapObject instanceof H.map.Group) {
this.areaStyle(mapObject.getObjects());
}
}
});
reader.parseData(area.shape);

const objects = reader.getParsedObjects();
if (objects.length > 1) {
console.error("There are some unhandled area objects.");
}
const object = objects[0];

const group = this.getAreasGroup();
group.addObject(object);
}

private getAreasGroup() {
// https://developer.here.com/documentation/maps/api_reference/H.map.Group.html
if (this.m_areasGroup === undefined) {
this.m_areasGroup = new H.map.Group({ zIndex: 10, volatility: true } as any);
this.m_map.addObject(this.m_areasGroup);
}

return this.m_areasGroup;
}

private readData(url: string): Promise<string> {
return new Promise((resolve, reject) => {
const request = new XMLHttpRequest();
request.open('GET', url, true);
request.send(null);
request.onreadystatechange = () => {
if (request.response && request.readyState == 4) {
resolve(request.response);
}
}
});
}

private setupMap() {
const apikey = '';

// Initialize the platform object:
const platform = new H.service.Platform({
apikey
} as any);

// Obtain the default map types from the platform object
const maptypes = platform.createDefaultLayers();

// Instantiate (and display) a map object:
this.m_map = new H.Map(
document.getElementById("mapContainer"),
(maptypes as any).vector.normal.map,
{
zoom: 6,
center: { lng: 10, lat: 42 }
});

// Enable the event system on the map instance:
const mapEvents = new H.mapevents.MapEvents(this.m_map);

new H.mapevents.Behavior(mapEvents);

H.ui.UI.createDefault(this.m_map, maptypes, 'en-US');

this.m_map.addEventListener('mapviewchangeend', () => {
this.renderAreas();
});

this.m_map.addEventListener('tap', async (event: any) => {
if (!(event.target instanceof H.map.Polygon)) {
return;
}

if (this.m_lastActiveArea) {
this.m_lastActiveArea.setStyle(this.m_normalAreaStyle);
}

event.target.setStyle(this.m_activeAreaStyle);
this.m_lastActiveArea = event.target;
});
}

}

const gcm = new GCM();document.addEventListener("DOMContentLoaded", () => gcm.startApp());

最佳答案

尝试将您的几何图形存储到 Fleet Telematics Custom Location Extension (CLE) 层中,然后使用 JS 库显示它们。

将几何图形存储到 CLE 层中:User's guideDeveloper's guide

使用 HERE JS 库显示 CLE 层:Developer's guide

关于javascript - 是否可以使用 “HERE Maps API for JavaScript” 以可接受的性能渲染邮政编码边框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59542627/

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