Then I split the data in separate tables for creating different layers in GeoServer.
My query to create a separate water layer:
insert into osm.water(osm_id, name, geom)
SELECT planet_osm_polygon.osm_id,
planet_osm_polygon.name,
st_multi(planet_osm_polygon.way)::geometry(MultiPolygon, 3857) as way
FROM planet_osm_polygon
WHERE planet_osm_polygon."natural" = 'water'::text
OR planet_osm_polygon."natural" = 'coastline'::text
OR planet_osm_polygon."natural" = 'strait'::text
OR planet_osm_polygon."natural" = 'wetland'::text
OR planet_osm_polygon."natural" = 'shoal'::text
OR planet_osm_polygon."natural" = 'bay'::text
OR planet_osm_polygon."natural" = 'beach'::text
OR planet_osm_polygon."waterway" = 'dock'::text
OR planet_osm_polygon."place" = 'sea'::text
OR planet_osm_polygon."landuse" = 'water'::text
OR planet_osm_polygon.water IS NOT NULL
OR planet_osm_polygon.waterway IS NOT NULL
OR planet_osm_polygon.wetland IS NOT NULL;
I have a problem with my water layer.
Not all waters are added to that layer. Example:
The water “Westerschelde Netherlands” is not colored blue. See image.
I do suspect that natural = coastline generates the issue. The thing is, in original data coastline is a (Multi)LineString. And usually, you will find it in planet_osm_line table. If you are using the data for whole planet, then the easiest thing would be to download water polygons from Water polygons and import it to PostgreSQL/PostGIS. If that’s only Netherlands, you can take a bounding box, create a polygon, and split the polygon by coastline.
I also created a map without planet_osm_polygon.“natural” = ‘coastline’::text and without the osm2pgsql --keep-coastlines parameter. That map has the same problem.
I think maybe it has to do something with the border of the country and the small dataset. The map in the example was a merged map with data sets for Netherlands, Belgium and Germany. With the dataset for only the Netherlands I have the same problem.
I bought me a bigger SSD and processing a dataset for Europe at this moment. I hope this will solve my problem. I let you know.
I don’t know if I need the coastlines. I tried that because I had problems. By the way I have the same problem in the north of the Netherlands (Eems). Also at the border (Germany).
Protected area is interesting, maybe I can add that to the query…
At this moment I’m processing the Europe dataset. This takes a lot of time (days). If that doesn’t work I give your suggestions a try.
Nee, een “gewone” kaart. GeoServer maakt van verschillende lagen weer een geheel. Per laag kan je, eenvoudig gezegd, een kleur aangeven. Omdat ik problemen met de waterlaag heb krijg je witte plekken.
Als je alleen Nederland wilt afbeelden dan moet netherlands.pbf genoeg zijn.
Zoals de pagina Coastline schrijft is de kustlijn anders dan andere objecten in OSM. Andere water-objecten zijn gesloten wegen, bijv. het IJsselmeer.
De kustlijn is geen gesloten weg, het is set van lijnen waarbij voor elke lijn geldt dat links van de lijn water is en land rechts van de lijn water. Het is niet voor niets dat je voor osm2pgsql een aparte parameter nodig hebt om dat kustlijnen mee te nemen
Ik heb het vermoeden dat het probleem is dat het water van de Westerschelde een polygon is die zich van Nederland tot in Belgie uitstrekt. Zie afbeelding (cirkel) Doordat ik alleen de dataset gebruik van Nederland krijg je een onvolledige polygon waarmee osm2pgsql niet mee om kan gaan. Ook omdat ik het zelfde probleem heb op de grens met Duitsland. Door de dataset van Europa te gebruiken hoop ik wat meer duidelijkheid te krijgen wat betreft mijn vermoedens.
Ik ben nu eerst bezig met het verwerken van europe-latest.osm.pbf. Zolang dat bezig is kan ik geen andere dingen testen.
create schema if not exists osm;
drop table if exists osm.water;
create table osm.water(
id serial not null primary key,
osm_id integer,
name text,
geom geometry(multipolygon, 3857)
);
create index gix_water on osm.water using gist(geom);
delete from osm.water;
insert into osm.water(osm_id, name, geom)
SELECT planet_osm_polygon.osm_id,
planet_osm_polygon.name,
st_multi(planet_osm_polygon.way)::geometry(MultiPolygon, 3857) as way
FROM planet_osm_polygon
WHERE planet_osm_polygon."natural" = 'coastline'::text;
Ik zie nu maar een heel klein stuke coastline (zie afbeelding):
Het enige wat wordt getoond zijn de twee eilanden in de Westerschelde omdat dat gesloten objecten zijn, de rest is zoals ik eerder beschreef collectie lijnen waarbij links lands is en rechts water.
Het probleem zit niet in de data maar hoe die wordt weergegeven, ik vermoed dat dat GeoServer is en daar heb ik geen ervaring mee.
Nee, ook dat zal niet werken, de kustlijn is opgebouwd uit wegen als dit stuk kustlijn van de Westerschelde maar ook eilanden zoals De Bol. Je zult dus eerst alle stukken kustlijn aan elkaar moeten plakken maar ik zou verwachten dat GeoServer speciale ondersteuning heeft voor kustlijnen.
Het lijkt mij dat GeoServer het niet goed ondersteunt maar ik ben nog maar net bezig zowel OSM als GeoServer. Dus het kan ook best zijn dat het wel mogelijk is.
Ik heb de benodigde wateren als shapefile kunnen downloaden:
Met deze shapefile heb ik een laag gemaakt in GeoServer. Voor de duidelijkheid heb ik hem rood gemaakt. Later wordt dit lichtblauw. Met de water layer er boven is het nu goed.
Yep, as suggested The thing with --keep-coastlines is, that neither the zeeland-latest.osm.pbf, neither europe set doesn’t have all coastlines required to create the proper polygon. I’m glad you found the solution.
The coastline is handled somewhat differently than most other features in OSM. To mark it ways with the tag natural=coastline are used. Those ways need to connect end-to-end to form an unbroken line around every island and every continent. And the land always has to be on the left side, the water on the right side of those ways.
You might have the luck and get it without gaps, but I would stick to already prepared data set from Water polygons - that’s really easiest way.
WITH bbox AS (
SELECT ST_Envelope(way)
FROM planet_osm_polygon
WHERE planet_osm_polygon.boundary = 'administrative'
AND planet_osm_polygon.admin_level = '2'
AND name = 'Polska'
),
splitline AS (
SELECT ST_UNION(way) FROM planet_osm_line
WHERE planet_osm_line.natural = 'coastline'
)
SELECT ST_Split(bbox, splitline)
Haven’t tested right now, as I don’t have coastlines in my db.
That ST_Split is al little difficult. I don’t really need that at the moment. I keep it in mind, maybe I need it in the future. Then I spend some more time on it to get it working.