[gdal-dev] Fwd: How to add labels to DEM contour lines

Cainã K. Campos rupestre.campos at gmail.com
Thu Jul 18 09:22:11 PDT 2024


Hi  KC,

I believe it is the right place for your question, maybe no one could
really check it out.
While I have not relied on OGR_STYLE on the command line, I have read a lot
of practical examples looking for how to create a geoPDF a few days ago.
So check out this guides and try to change only the format from PDF to KML

https://spatialthoughts.com/2015/10/25/geopdf-gdal/
http://latuviitta.org/documents/Geospatial_PDF_maps_from_OSM_with_GDAL.pdf

For me what worked for PDF was to use feature.SetStyleString(style_string)
and add to output data source using python, may work for KML too below a
minimal example.
I created a KMZ on the project but I used another library for it, not gdal
itself but I will provide it here also if it helps .

Also I noticed that the PDF Label is not showing up on the result as I
expected neither I used the label on the KML so cannot help you on this for
now, just the styling and popup on the kml, but if I get any progress I
report to you.

My Best,
Cainã K. Campos

import json
from osgeo import ogr, osr, gdal
import matplotlib.colors as mcolors
import simplekml

def get_style_rules():
return {
"hidrografia": {"color": "blue", "fillColor": "blue", "fillOpacity": 0.6,
"opacity":0.5, "weight":0},
"area_imovel": {"color": "yellow", "fillColor": "white", "fillOpacity":0.01,
"weight":3, "opacity":0.8},
"apps": {"color": "red", "fillColor": "red", "fillOpacity": 0.3, "opacity":
0.5, "weight":0}
}

def color_name_to_hex_with_alpha(color_name, alpha=1.0, invert_alpha=False,
bgr=False):
"""
Convert a color name to a hex value with alpha (transparency).
Alpha should be a float between 0.0 (fully transparent) and 1.0 (fully
opaque).
"""
try:
# Get the hex color code without the '#' and convert to RGBA
hex_color = mcolors.to_hex(color_name)[1:]

# Scale alpha to 255 and convert to hex
alpha_hex = f"{int(alpha * 255):02X}"
if bgr:
hex_color = f"{hex_color[-2:]}{hex_color[2:4]}{hex_color[:2]}"
if invert_alpha:
return f"#{alpha_hex}{hex_color}"
return f"#{hex_color}{alpha_hex}"
except ValueError:
return "#000000FF" # Default to black with full opacity if color name not
found

def create_styled_layer_from_geojson(geojson_data, output_pdf):
# Create a temporary file to store the GeoJSON data
temp_geojson_file = '/tmp/temp_geojson.json'
with open(temp_geojson_file, 'w') as f:
json.dump(geojson_data, f)

# Open the GeoJSON file with OGR
driver = ogr.GetDriverByName('GeoJSON')
dataSource = driver.Open(temp_geojson_file, 0) # 0 means read-only

if dataSource is None:
print('Could not open file')
return

# Create a spatial reference
spatialRef = osr.SpatialReference()
spatialRef.ImportFromEPSG(4326) # Assuming WGS84

# Create the output PDF driver
driver_pdf = gdal.GetDriverByName('PDF')
if driver_pdf is None:
print('PDF driver is not available.')
return

# Create the PDF file
output_ds = driver_pdf.Create(output_pdf, 0, 0, 0, gdal.GDT_Unknown)

if output_ds is None:
print('Could not create PDF file')
return

output_layer = output_ds.CreateLayer('layer', srs=spatialRef, geom_type=ogr.
wkbUnknown)
in_lyr = dataSource.GetLayerByIndex(0)
lyr_def = in_lyr.GetLayerDefn ()
for i in range(lyr_def.GetFieldCount()):
output_layer.CreateField ( lyr_def.GetFieldDefn(i) )

# Iterate through features and style them
for feature in dataSource.GetLayer():
geom = feature.GetGeometryRef()
cod_tema = feature.GetField('cod_tema')
car_code = feature.GetField('cod_imovel')

style = get_style_cod_theme(cod_tema)
fillOpacity = style.get('fillOpacity', 0.5)
# Apply the style to the feature
color = color_name_to_hex_with_alpha(style['color'], style.get("opacity",
0.5))
fillColor = color_name_to_hex_with_alpha(style.get('fillColor', 'none'),
fillOpacity)
line_width = style.get("weight", 1)
# Create a new feature with the same geometry
new_feature = ogr.Feature(output_layer.GetLayerDefn())
new_feature.SetGeometry(geom.Clone())

# Set the style of the new feature
style_string = f"PEN(c:{color},w:{line_width}mm)"
if fillColor != 'none':
style_string += f";BRUSH(fc:{fillColor})"
style_string += f';LABEL(f:"Arial, Helvetica", s:26pt, t:"{car_code}")'
new_feature.SetStyleString(style_string)

# Add all attributes to the feature
for i in range(feature.GetFieldCount()):
field_name = feature.GetFieldDefnRef(i).GetName()
field_value = feature.GetField(field_name)
new_feature.SetField(field_name, field_value)

output_layer.CreateFeature(new_feature)

# Destroy the feature to free resources
new_feature = None

# Close the data sources
dataSource = None
output_ds = None

def create_kmz_from_geojson(geojson_data, output_kmz):
# Create a KML object
kml = simplekml.Kml()

# Iterate through features and style them
for feature in geojson_data['features']:
cod_tema = feature['properties'].get('cod_tema')
style = get_style_cod_theme(cod_tema)

# Extract geometry and properties
geom = feature['geometry']
properties = feature['properties']

# Create a KML placemark for the feature
placemark = kml.newmultigeometry(name=cod_tema)
for coords in geom['coordinates']:
if geom['type'] == 'Polygon':
placemark.newpolygon(outerboundaryis=coords)
elif geom['type'] == 'MultiPolygon':
for polygon_coords in coords:
placemark.newpolygon(outerboundaryis=polygon_coords)

# Apply style to the placemark
color = color_name_to_hex_with_alpha(
style['color'],
style.get("opacity",0.5),
invert_alpha=True,
bgr=True
).upper()

fillColor = style.get('fillColor', 'none')
if fillColor != 'none':
fillColor = color_name_to_hex_with_alpha(
fillColor,
style.get("fillOpacity",0.5),
invert_alpha=True,
bgr=True
).upper()

placemark.style.linestyle.color = color.replace("#","")
placemark.style.linestyle.width = style.get('weight', 1)
if fillColor != 'none':
placemark.style.polystyle.color = fillColor.replace("#","")

# Add attributes as description
description = "<br>".join(f"<b>{key}</b>: {value}" for key, value in
properties.items())
placemark.description = description

# Save KML to a KMZ file
kml.savekmz(output_kmz)


On Thu, Jul 18, 2024 at 12:51 PM Open Land LLC via gdal-dev <
gdal-dev at lists.osgeo.org> wrote:

> Hi Everyone,
>
> I just wanted to ask - Is this the right place to post questions? I put in
> a post several days ago, and just want to make sure I'm putting it in the
> right place, because I have not posted to this group before. Thank you - KC
>
> ---------- Forwarded message ---------
> From: Open Land LLC <realoption11 at gmail.com>
> Date: Mon, Jul 15, 2024 at 9:00 PM
> Subject: How to add labels to DEM contour lines
> To: <gdal-dev at lists.osgeo.org>
>
>
> Hi everyone, this is my first post. I've also posted this to
> https://stackoverflow.com/questions/78751101/labelling-contour-lines-with-ogr-style
>
> I'm trying to add labels to DEM contour lines.
>
> I'm working with GDAL 3.6.2. , which I installed using Anaconda . I have
> some DEM data from USGS which I wrote as a contour map to a KML file using:
>
>     gdal_contour small.tif /home/ubuntu/node/geotools/contour.kml -i 3.0
> -f KML -a ELEVATION
>
> When I open contour.kml in vim, I can see that its made up of features
> like:
>
> <Placemark>
>
> <Style><LineStyle><color>ff0000ff</color></LineStyle><PolyStyle><fill>0</fill></PolyStyle></Style>
> <ExtendedData><SchemaData schemaUrl="#contour">
> <SimpleData name="ID">39</SimpleData>
> <SimpleData name="ELEVATION">525</SimpleData>
> </SchemaData></ExtendedData>
> <LineString><coordinates>-89.2626638689733,46.1525006611575
> -89.262663868958,46.1525469572921 -89.2627325352002,46.152622208059
> -89.2628251277396,46.1526266807347 -89.2629177202847,46.1526141000471
> -89.2629982621728,46.1525469573863
> -89.2629982621882,46.1525006612516</coordinates></LineString>
> </Placemark>
>
> Clearly there is a style component available , but I'm not sure how to
> work with it to add elevation labels or custom colours. My suspicion is
> that OGR_STYLE is used to do things like this (
> https://github.com/OSGeo/gdal/issues/835)(https://gdal.org/user/ogr_sql_dialect.html#ogr-style
> ), but I can't find any examples. How can this be done?
>
> Thank you very much,
>
> KC
>
> _______________________________________________
> gdal-dev mailing list
> gdal-dev at lists.osgeo.org
> https://lists.osgeo.org/mailman/listinfo/gdal-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/gdal-dev/attachments/20240718/efbc89e2/attachment-0001.htm>


More information about the gdal-dev mailing list