Нагрузку можно прикинуть на практике. Возьмём прямоугольную область, например, на северо-западе Московской области и посмотрим, сколько времени нужно на обработку запросов по поиску участков дорог внутри полигонов place=* и вне их, и сравним с операцией, по которой уже есть общая статистика загрузки, применив её к той же площади.
Фильтрацию возьмём простейшую, на каждом этапе не будем обрабатывать только highway=track.
Сначала выберем все дороги, не проходящие через place=*, а также типа highway=track.
explain (analyze) select planet_osm_line.way from planet_osm_line, planet_osm_polygon where planet_osm_polygon.place is not null
and planet_osm_polygon.way && st_transform(ST_SetSRID(box2d(ST_GeomFromText('LINESTRING(36.464133 56.080593, 37.224936 55.694698)',4326)),
4326), 3857) and planet_osm_line.highway is not null and planet_osm_line.way &&
st_transform(ST_SetSRID(box2d(ST_GeomFromText('LINESTRING(36.464133 56.080593, 37.224936 55.694698)',4326)), 4326), 3857) and ( not
st_intersects(planet_osm_line.way, planet_osm_polygon.way) or planet_osm_line.highway = 'track');
[skip]
Planning Time: 7.783 ms
Execution Time: 9868.915 ms
(20 строк)
Потом выберем все части дорог внутри полигонов place=*.
opentopomap=# explain (analyze) select st_intersection(planet_osm_line.way, planet_osm_polygon.way) from planet_osm_line, planet_osm_polygon
where planet_osm_polygon.place is not null and planet_osm_polygon.way && st_transform(ST_SetSRID(box2d(ST_GeomFromText('LINESTRING(36.464133
56.080593, 37.224936 55.694698)',4326)), 4326), 3857) and planet_osm_line.highway != 'track' and planet_osm_line.way &&
st_transform(ST_SetSRID(box2d(ST_GeomFromText('LINESTRING(36.464133 56.080593, 37.224936 55.694698)',4326)), 4326), 3857) and
st_intersects(planet_osm_line.way, planet_osm_polygon.way);
[skip]
Planning Time: 5.914 ms
Execution Time: 8477.381 ms
(17 строк)
И в конце выберем отрезки дорог, “торчащие” из населённых пунктов:
opentopomap=# explain (analyze) select st_difference(planet_osm_line.way, planet_osm_polygon.way) from planet_osm_line, planet_osm_polygon
where planet_osm_polygon.place is not null and planet_osm_polygon.way && st_transform(ST_SetSRID(box2d(ST_GeomFromText('LINESTRING(36.464133
56.080593, 37.224936 55.694698)',4326)), 4326), 3857) and planet_osm_line.highway != 'track' and planet_osm_line.way &&
st_transform(ST_SetSRID(box2d(ST_GeomFromText('LINESTRING(36.464133 56.080593, 37.224936 55.694698)',4326)), 4326), 3857) and
st_intersects(planet_osm_line.way, planet_osm_polygon.way);
[skip]
Planning Time: 8.060 ms
Execution Time: 8801.962 ms
(17 строк)
И теперь сравним это, например, одной из операций объединения полигонов леса на той же области:
opentopomap=# explain (analyze) select ST_Union("way") as "way","natural",landuse,leaf_type from (SELECT "way","natural",landuse,leaf_type FROM
planet_osm_polygon WHERE "natural" = 'wood' or landuse IN ('wood', 'forest')) AS landuse where way &&
st_transform(ST_SetSRID(box2d(ST_GeomFromText('LINESTRING(36.464133 56.080593, 37.224936 55.694698)',4326)), 4326), 3857) group by
"natural",leaf_type,landuse;
[skip]
Planning Time: 0.464 ms
Execution Time: 12697.379 ms
(14 строк)
Про последнюю операцию по статистике известно, что она занимает около 11% процессорного времени от всех других операций.
Операции выборки дорог в сумме заняли чуть больше 27 секунд, сшивка полигонов - около 13. То есть первые операции длились более чем в два раза дольше одной из самых ресурсоёмких операций при рендеринге, при том, что была применена только простейшая фильтрация.
Но полигоны сшивать необходимо, так как иначе в лесу появляются артефакты, дезориентирующие пользователя, чего не скажешь о дорогах.
Но, изучив подробнее ситуацию с дорогами, я понял, что можно доработать существующую цветовую схему маркировки дорог без ущерба для общего дизайна карты и лёгкости её прочтения, при том, что будет более полно учитываться тип покрытия и не будет сильно загружаться база. Для этого для дорог типа tertiary и secondary нужно сделать заливку цветом в зависимости от типа покрытия, как это уже сделано для дорог типа unclassified, но с небольшим отличием - если вообще нет тега surface, то оптимистично заливать дорогу жёлтым, а не белым. Тогда за пределами населённых пунктов, если все теги проставлены правильно, можно будет точно сказать, что “жёлтые дороги” - с твёрдым покрытием, “белые” - нет. Твёрдым считается покрытие, когда surface = ‘paved’ , ‘asphalt’, ‘concrete’ , ‘paving_stones’, ‘sett’, ‘cobblestone’, ‘metal’.
Через некоторое время я добавлю эту схему.