3

У меня есть приложение, которое рисует многоугольники на карте Карт Google. Я использую угловой для переднего конца и NodeJS api для обслуживания своих данных полигона.Полигоны Google Карт замедляют работу браузера

В настоящее время я загружаю около 300 полигонов с около 10 000 латвийских коордов каждый, но у меня есть данные с разбивкой по страницам, поэтому я получаю только одну десятую от общего количества полигонов. Я использую угловой модуль сверху Angular Google Maps, сам проект кажется немного мертвым, учитывая страницу проблем GitHub, но я не думаю, что это действительно имеет значение.

Я установил для изменяемого флага значение false, но даже после отображения только 30 из этих сложных полигонов браузер, похоже, замедляет значительное количество. Этого не происходит, когда я вообще не рисую многоугольники.

Я обнаружил, что таблицы KML или Fusion рекомендуются очень часто, но я бы хотел надеяться, что мне не придется преобразовывать мои данные из-за огромного количества его.

У кого-нибудь была аналогичная проблема?

ответ

5

Я занимался аналогичной проблемой в прошлом. Во-первых, я хочу упомянуть, что я не использовал никаких обложек API JS API, таких как Угловые Карты Google или NgMaps, потому что я считаю, что эти библиотеки не обертывают много полезной функциональности API или делают это так неэффективно.

Я использовал google.maps.Datalayer для отображения многоугольников. Я считаю, что этот подход имеет лучшую производительность, чем использование google.maps.Polygon. Итак, это мой первый совет, дайте data layer попробовать вместо обычных полигонов. Она не требует радикальных преобразований данных, так как слой данных имеет addGeoJson(geoJsonObject) метод и поскольку у вас есть ваши данные в виде lat и lngs это должно быть легко генерировать GeoJSON Feature объект из него, это будет выглядеть примерно так:

{ 
"type": "Feature", 
"properties": { ... }, 
"geometry": { 
    "type": "Polygon", 
    "coordinates": [ [lat1, lng1], [lat2, lng2], .. (your data) ] 
    } 
} 

Или используйте библиотеку, чтобы сгенерировать ее для вас. Преимущество data layer заключается в том, что он предоставляет множество функций, таких как пользовательский стиль, взаимодействие с событиями мыши и т. Д. Я предлагаю вам взглянуть на мой пример BoundariesExample, который использует DataLayer, доступный на Github или этом answer on SO. (Кстати, вы также можете добавить многоугольник Data Layer легко, как это: map.data.add({geometry: new google.maps.Data.Polygon([coords])}) но я предлагаю выше подход, так как библиотеки я упомяну позже работа с форматом GeoJSON)

Я был, хотя, отображающий более 30K полигонов на карте, многие из них были очень сложными. Поэтому, если вы все еще испытываете замедленность, у меня есть еще советы по оптимизации:

1.Упростите многоугольники перед их отображением на карте. То есть, если вы не против удаления некоторых вершин из ваших полигонов в обмен на лучшую производительность. Вы можете добавить все свои полигоны в один объект GeoJSON, а затем воспользоваться утилитой mapshaper, чтобы упростить их с помощью specialised algorithms (интерактивный пример here). Я не уверен, что утилита может быть включена в библиотеку в проект node.js, так как я запускал ее как внешнюю утилиту с PHP, но это очень упростило ваши полигоны. С 300 полигонами я подозреваю, что вы сможете сделать это «на лету», или, конечно, вы можете кэшировать результаты. Используйте упрощение, если это возможно, поскольку оно имеет все методы, которые оказывают наибольшее влияние на производительность.

2.Merge полигоны. Я выяснил, что сокращение количества полигонов (сворачивание их на один, например) повышает производительность.Если ваши многоугольники не должны существовать как отдельные объекты (поэтому, если все они могут быть окрашены в один цвет, отображать одно и то же всплывающее окно при нажатии ...), вы можете объединить их. mapshaperdissolve команда поможет вам.

3. Добавьте несколько слоев данных и загрузите только полигоны (частично), видимые на карте. Так, например, при больших уровнях масштабирования, когда пользователь не может даже видеть такие детали, как ваши данные, вы можете упростить полигоны, используя метод 1, и при увеличении масштаба, скрыть верхний уровень и отобразить неупрощенные полигоны, и только те, которые падают (даже частично) в вашем текущем виде карты. Таким образом, вы будете вычислять ограничивающие прямоугольники для всех ваших полигонов, использовать ограничивающий прямоугольник текущего вида карты и загружать только те, которые перекрываются. После того, как пользователь переместит карту, вы можете получить другую. Когда они снова уменьшат масштаб, скройте нижний уровень и отобразите верхний уровень. Похоже, что когда уровень данных features (функция является полигоном, линией, точкой или их коллекцией) скрыты, они не влияют на производительность.

Конечно, вы можете применить комбинацию вышеуказанных приемов. Также вы можете использовать FusionLayer, но это связано с некоторыми ограничениями (перечисленными в docs), с уровнем Data у вас больше контроля.

+0

Спасибо за подробный ответ, Matej! Я думаю, что я попытаюсь отказаться от текущей Угловой Директивы Google Maps от текущего решения и протестировать Google.Maps.DataLayer без какого-либо стороннего программного обеспечения. – NicT

+0

Нет проблем. Я предлагаю вам также взглянуть на упрощение. Я испытал самые большие улучшения в производительности при его использовании, и, поскольку вы можете указать процент упрощения, вероятно, вы найдете процент, когда упрощение не повредит вам визуально, но значительно улучшит производительность. –

Смежные вопросы