Back to main SpatiaLite-Tools Wiki page
spatialite_dem - Introduction
Goals of Tool spatialite_dem- Create a Dem-Database from 1 or more xyz-files
- Query of Dem-Database (-fetch_yx)
- Configuration of default Dem-Database to use and default srid for queries
- Updating a Database SpatialTables with Z-Values from Dem-Database (-updatez)
- Sample Photos
- Sample Points
- Sql used to create the sample points
- Screenshot showing the test points (Scale 1:15)
- Screenshot showing the test points (Scale 1:100)
- Determin if DEM-Points reflect the heights of buildings or ground level
- spatialite_dem --save_conf
- spatialite_dem --help
Create a Dem-Database from 1 or more xyz-files
-
this can be a single xyz-file
-
a directory of xyz-files
-
a list-file, each line containing one xyz-file-name,
whereby list file must be in the directory that contains the listed files
Notes: Before importing, the first line of each file will read , checking if 3 double values can be properly converted
During importing, this memory table is read, sorting by point_y ASC, point_x ASC Goal is to import all points sorted as:
The created table will contain the x/y/z values as doubles and a POINTZ geometry with the given srid. Then a RecoverGeometryColumn and CreateSpatialIndex is done. For my 1.116 billion Berlin-Database
Sort command for a xyz-file: In theory;
For Linux, a correct usage would be:
For gdal, it is crucial that the .xyz- file is sorted in the Y-Direction
where as the correctly sorted input.xyz, worked correctly
For spatialite_dem, it is only cosmetic
|
Query of Dem-Database (-fetch_yx)
This is very swift, mostly around 3 milli-secondsspatialite_dem -v -fetchz_xy 24700.55278283251 20674.74537357586 Dem: srid 25833 Dem: extent min x/y(370000.0000000,5798000.0000000) max x/y(415999.0000000,5837999.0000000) Dem: extent width(45999.0000000) height(39999.0000000) Dem: rows_count(utm_point) 1116000000 Dem: resolution(utm_point) 1.6486685 Dem: geometry_type(1001) has_z1 has_m0 Dem: spatial_index_enabled1 Dem '/home/mj10777/000_links/build_berlin_data/build.berlin_admin/geometry_admin/source_db/2007.berlin.dhhn92.db' TABLEberlin_dhhn92_2007 with GEOMETRY-Columnutm_point -W-> -rdem was set. Using: resolution(0.5000000), overriding the calculated value: 1.6486685 FetchZ modus: with default_srid[3068] x24700.5527828 y20674.7453736 has_m0 FetchZ modus: with dem_srid[25833] x391427.4994515 y5819297.5054299 z33.5600000 >> time needed: 07 milli-secs
Note:
|
Configuration of default Dem-Database to use and default srid for queries
can be saved with -save_conf to file default 'spatialite-dem.conf'With:
- export SPATIALITE_DEM=/long/path/to/file/2007.berlin.dhhn92.conf
spatialite_dem will read that file first, setting the default values
The Database I created was called '2007.berlin.dhhn92.db' and placed in the '/long/path/to/file/' directory.
Using the -sniff parameter, the settings can be checked:
spatialite_dem -sniff -d /long/path/to/file/berlin_admin_geometries.db -t berlin_street_segments -g soldner_segment -ddem /long/path/to/file/2007.berlin.dhhn92.db -tdem berlin_dhhn92_2007 -gdem utm_pointWith SPATIALITE_DEM having been set, using -save_conf, would save the config to the file pointed to in SPATIALITE_DEM.resulting also with
Source: srid 3068 ... Source Database: has passed all checks. ... Dem: srid 25833 ... Dem: resolution(utm_point) 1.6486685 ... Dem Database: has passed all checks. Sniffing modus: All pre-conditions have been fulfilled. to start update, use the '-updatez' parameter. to save dem-conf, use the '-save_conf' parameter.
Since I will use this Database for 99% of my needs, I have added the export command to my local .bashrc.
So when calling (with out -v):
spatialite_dem -fetchz_xy 24700.55278283251 20674.74537357586 33.5600000with out having to give:
- -d /long/path/to/file/berlin_admin_geometries.db
- -t berlin_street_segments
- -g soldner_segment
- -ddem /long/path/to/file/2007.berlin.dhhn92.db
- -tdem berlin_dhhn92_2007
- -gdem utm_point
- -rdem=0.5
over and over again.
Important is setting/editing the dem_resolution/-rdem parameter in the conf file
- since an automatic calculation is not always possible
Since I forgot to use the '-rdem' parameter when using '-save_conf':
-rdem 0.50
this would then have to be changed in the file:
# -- -- ---------------------------------- -- # Area around given point to Query Dem-Geometry in units of Dem-Srid # -> Rule: a Dem with 1m resolution: min=0.50 dem_resolution=0.50 # -- -- ---------------------------------- --
In this case the Database contains only the Open-Data points of Berlin,
For this reason the -rdem parameter, overriding the calculated resolution, should always be used. |
Notes: -v
|
Updating a Database SpatialTables with Z-Values from Dem-Database (-updatez)
Preconditions: That a copy from an origianl TABLE has been made that contains a Geometry of the Z or ZM Geometry type (using CastToXYZ or CastToXYZM).
including all MULTI-Types of POINT, LINESTRING and POLYGON
-sniff
|
A Sql-Script to convert one TABLE from an XY-based Database to XYZ-based Database could look like this:
-- -- ---------------------------------- -- -- spatialite berlin_admin_geometries.xyz.db < create.xyz.berlin_admin_geometries.sql -- -- ---------------------------------- -- SELECT DateTime('now','localtime'),'ATTACH DATABASE: berlin_admin_geometries.db'; ATTACH DATABASE "../source_db/berlin_admin_geometries.db" AS db_import; --- -- ---------------------------------- -- -- 20170911: adapted for XYZ support -- -- ---------------------------------- -- BEGIN; -- -- ---------------------------------- -- SELECT DateTime('now','localtime'),'creating table berlin_polygons'; DROP TABLE IF EXISTS berlin_polygons; CREATE TABLE berlin_polygons ( id_geometry INTEGER PRIMARY KEY, id_admin INTEGER DEFAULT 0, name TEXT DEFAULT '', notes TEXT DEFAULT '', text TEXT DEFAULT '', admin_level INTEGER DEFAULT 10, valid_since DATE DEFAULT '0001-01-01', valid_until DATE DEFAULT '3000-01-01', changed_type INTEGER DEFAULT 3, -- 1=name,2=belongs,3=borders,4=house_numbers id_belongs_to INTEGER DEFAULT 0, belongs_to TEXT DEFAULT '', -- length of ExteriorRing meters_length DOUBLE DEFAULT 0, -- Area of ExteriorRing meters_area DOUBLE DEFAULT 0 ); SELECT AddGeometryColumn('berlin_polygons','soldner_linestring',3068,'MULTILINESTRING','XYZ'); SELECT CreateSpatialIndex('berlin_polygons','soldner_linestring'); SELECT AddGeometryColumn('berlin_polygons','soldner_polygon',3068,'MULTIPOLYGON','XYZ'); SELECT CreateSpatialIndex('berlin_polygons','soldner_polygon'); SELECT AddGeometryColumn('berlin_polygons','soldner_ring',3068,'MULTIPOLYGON','XYZ'); SELECT CreateSpatialIndex('berlin_polygons','soldner_ring'); SELECT AddGeometryColumn('berlin_polygons','soldner_center',3068,'POINT','XYZ'); SELECT CreateSpatialIndex('berlin_polygons','soldner_center'); -- -- ---------------------------------- -- SELECT DateTime('now','localtime'),'filling table berlin_polygons based on admin_changed_borders'; INSERT INTO berlin_polygons (id_admin,name,notes,text,admin_level,valid_since,valid_until,id_belongs_to,belongs_to,soldner_polygon,soldner_ring, soldner_linestring,soldner_center) SELECT id_admin,name,notes,text,admin_level,valid_since,valid_until,id_belongs_to,belongs_to, -- convert (possibly a) XY MULTIPOLYGON to a XYZ MULTIPOLYGON CastToXYZ(soldner_polygon), -- create the Ring from the XY MULTIPOLYGON CastToXYZ(CastToMultiPolygon(ST_UnaryUnion(soldner_polygon))), -- create the LINESTRING from the XY Ring CastToXYZ(CastToMultiLinestring(ST_LinesFromRings(soldner_ring))), -- create the Center from the XY MULTIPOLYGON CastToXYZ(ST_Centroid(soldner_polygon)) FROM db_import.berlin_polygons WHERE ( (soldner_polygon IS NOT NULL) ) ORDER BY admin_level,id_admin, valid_since; -- -- ---------------------------------- -- -- result in meters of Polygon - without Area of any possible InteriorRings UPDATE berlin_polygons SET meters_area=ST_Area(soldner_polygon); -- result in meters of ExteriorRing - the result of soldner_linestring is longer (all lines) UPDATE berlin_polygons SET meters_length=ST_Perimeter(soldner_ring); -- -- ---------------------------------- -- SELECT UpdateLayerStatistics(); -- -- ---------------------------------- -- COMMIT; SELECT DateTime('now','localtime'),'All Geometries now contain Z-Values set with 0'; -- 709 records -- -- ---------------------------------- -- |
With the Database berlin_admin_geometries.xyz.db
- we can now UPDATE the Geometries with the nearest (for each POINT in the Geometry) found POINT from the Dem-Database
- -v will be set so that all messages are shown
- but adding -v so that information messages will be shown
-
First we will use the -sniff to check if the command systax is correct
spatialite_dem -sniff -updatez --db-path berlin_admin_geometries.xyz.db -t berlin_polygons -g soldner_polygon SQLite version: 3.17.0 SpatiaLite version: 4.5.0-devel |
Second we will remove the -sniff command, so that -updatez will be called
spatialite_dem -v -updatez --db-path berlin_admin_geometries.xyz.db -t berlin_polygons -g soldner_polygon |
Third we will remove the -v command, so that -updatez without any information messages
- returning only a return code 0=correct or 1=error, for use with bash
spatialite_dem -updatez --db-path berlin_admin_geometries.xyz.db -t berlin_polygons -g soldner_ring spatialite_dem -updatez --db-path berlin_admin_geometries.xyz.db -t berlin_polygons -g soldner_linestring spatialite_dem -updatez --db-path berlin_admin_geometries.xyz.db -t berlin_polygons -g soldner_center |
Process: If the srid of the Geometry is different that the srid of the Dem-Points
|
Notes: Return code of tool:
|
Sample Photos
Sample Points The Database used here used srid 25833 (ETRS89 / UTM zone 33N) but displays the map with srid 3068 (DHDN / Soldner Berlin)
Sample Points
Sql used to create the sample pointsSql used to create the above listSELECT id_dem, point_x AS x_utm, point_y AS y_utm, point_z AS Z, ST_X(ST_Transform(utm_point,3068)) AS x_soldner, ST_Y(ST_Transform(utm_point,3068)) AS x_soldner, ST_Distance(utm_point,ST_Transform(MakePoint(24700.55278283251,20674.74537357586,3068),25833)) AS distance_meters FROM "berlin_dhhn92_2007" WHERE ( -- First condition ( -- Out of the 1.116.000.000 records, select only those that are in range 4 will be returned -- for a SpatialView, the Primary-Key must be used, otherwise ROWID can be used id_dem IN ( -- Use the Spatialite internal logic to simplify the SQL-Query, avoiding rounding errors that could miss a valid geometry SELECT ROWID FROM SpatialIndex WHERE ( -- Use the created index for the given TABLE -- To query an ATTACHED Database, replace 'main' with the used schema-name -- > 'DB=main.' for a non-ATTACHED Database is not mandatory (f_table_name = 'DB=main.berlin_dhhn92_2007') AND -- Use the given Geometry-Column mandatory only where there is more than 1 Geometry-Column (f_geometry_column = 'utm_point') AND -- search an area 0.5 meters around the given point (= 1 meter width/height) (search_frame = ST_Buffer(ST_Transform(MakePoint(24700.55278283251,20674.74537357586,3068),25833),0.5)) ) ) ) ) ORDER BY distance; |
Screenshot showing the test points (Scale 1:15)
- Area around a given point to search for: 1.0/2=0.5 - Circles width/height 1 Meter
Agua Point : 24700.55278283251 20674.74537357586
- search the area around the Agua point (Circles width/height 1 Meter) for the nearest point, which is the Upper-Left green circle showing 33.56, with a distance of 0.702887 meters.
Since the SPATIALITE_DEM is set to a config file where default_srid=3068 and -rdem=0.5 is set, a simplified form of the command can be used:
spatialite_dem -fetchz_xy 24700.55278283251 20674.74537357586
33.5600000
(Upper-Left green circle)
spatialite_dem -fetchz_xy 24700.554 20674.745
33.6000000
(Upper-Right green circle)
spatialite_dem -fetchz_xy 24700.55 20674.70
33.6200000
(Lower-Left green circle)
spatialite_dem -fetchz_xy 24700.60 20674.70
33.6100000
(Lower-Right green circle)
This street intersection is not a cobble stoned street, so where does the 6 cm difference come from?
Screenshot showing the test points (Scale 1:100)
Here QGis is set to display srid 3068 (DHDN / Soldner Berlin)
-
which is the original settings of the georeferenced Map
The streets here are about 15 meters wide,
-
so one can see what a 1 meter DEM resolution really means.
The same area with QGis using using srid 25833 (ETRS89 / UTM zone 33N)
-
which is the original settings of the points
Determin if DEM-Points reflect the heights of buildings or ground level
The displayed '31' is the area of the northern part of my flat.
Height of a room: 2.71 meters
Height of the building (7 floors) would them be around 21 meters (22 is allowed in this area).
Street (upper left area) height is around 34.70
House (lower half) should be a good 20 meters higher, but is also around 34.70 meters
Conclusion: the height data does not reflect the building heights.
(would be interesting to learn how, during the post-processing, how the numbers were determined)
spatialite_dem --save_conf# -- -- ---------------------------------- -- # For use with spatialite_dem # -- -- ---------------------------------- -- # export SPATIALITE_DEM/long/path/to/file/2007.berlin.dhhn92.conf # -- -- ---------------------------------- -- # Full path to Spatialite-Database containing a Dem-POINTZ (or POINTZM) Geometry dem_path/long/path/to/file/2007.berlin.dhhn92.db # Table-Name containing a Dem-POINTZ (or POINTZM) Geometry dem_table=berlin_dhhn92_2007 # Geometry-Column containing a Dem-POINTZ (or POINTZM) Geometry dem_geometry=utm_point # Srid of Dem-Geometry dem_srid=25833 # -- -- ---------------------------------- -- # Area around given point to Query Dem-Geometry in units of Dem-Srid # -> Rule: a Dem with 1m resolution: min=0.50 dem_resolution=0.50 # -- -- ---------------------------------- -- # Default Srid of Queries against Dem-Geometry -fetchz_xy, -updatez default_srid=3068 # -- -- ---------------------------------- -- # Count of rows in Dem-Geometry dem_rows_count=1116000000 # Min X of Dem-Geometry dem_extent_minx=370000.0000000 # Max X of Dem-Geometry dem_extent_maxx=415999.0000000 # Min Y of Dem-Geometry dem_extent_miny=5798000.0000000 # Max Y of Dem-Geometry dem_extent_maxy=5837999.0000000 # Width of Dem-Area in Srid-Units dem_extent_width=45999.0000000 # Height of Dem-Area in Srid-Units dem_extent_height=39999.0000000 # -- -- ---------------------------------- -- |
Process: The main goal of the conf file is to simplify the usage of the tool
|
spatialite_dem --helpusage: spatialite_dem ARGLIST ============================================================== -h or --help print this help message ========================== Parameters ======================== -- -- ---------------- Dem-Data Database ---------------- -- -ddem or --dem-path pathname to the SpatiaLite Dem DB -tdem or --table-dem table_name SpatialTable or SpatialView -gdem or --geometry-dem-column col_name the Geometry column must be a POINT Z or a POINT ZM type -rdem or --dem-resolution of the dem points while searching the automatic resolution calculation is based on the row_count within the extent, which may not be correct! Use '-rdem' to set a realistic value-- -- -------------- Source-Update-Database ----------------- -- -d or --db-path pathname to the SpatiaLite DB -t or --table table_name, must be a SpatialTable -g or --geometry-column the Geometry column to update must be a Z or a ZM Dimension type use CastToXYZ(geom) or CastToXYZM(geom) to convert -- -- --------------- General Parameters ---------------- -- -mdem or --copy-m 0=no, 1= yes [default if exists] -default_srid or --srid for use with -fetchz -fetchz_xy x- and y-value for use with -fetchz -v or --verbose messages during -updatez and -fetchz -save_conf based on active -ddem , -tdem, -gdem and -srid when valid-- -- -------------------- Notes: ---------------------- -- -I-> the Z value will be copied from the nearest point found -I-> the Srid of the source Geometry and the Dem-POINT can be different -I-> when -fetchz_xy is used in a bash script, -v should not be used the z-value will then be retured as the result-- -- -------------------- Conf file: ------------------- -- -I-> if 'SPATIALITE_DEM' is set with the path to a file -I--> 'export SPATIALITE_DEM=/long/path/to/file/berlin_dhh92.conf' -I-> then '-save_conf' save the config to that file -I-> this file will be read on each application start, setting those values -I--> the parameters for : which Dem-Database and Geometry and the default_srid to use for queries -> would then not be needed-- -- ---------------- Importing .xyz files: ------------------- -- -I-> a single xyz.file or a directory containing .xyz files can be given for directories: only files with the extension .xyz will be searched for -I-> a single list.file inside a directory containing .xyz files can be given each line containing the file-name that must exist in that directory -I-> validty checks are done before importing xyz-files the first line may contain only 3 double values (point_x/y/z) if valid, the file-name and the point_x/y points are stored when importing, the list will be read based of the y/x points-- -- ---------------- Sorting .xyz files ---------------------- -- -I-> xyz.files should be sorted: y='South to North' and x='West to East': sort -n -k2 -k1 input_file.xyz -o output_file.sort.xyz =========================== Commands =========================== -sniff default analyse settings without UPDATE of z-values -updatez Perform UPDATE of z-values -fetchz Perform Query of z-values using -fetchz_x_y and default_srid will be assumed when using -fetchz_x_y -create_dem create Dem-Database using -ddem,-tdem, -gdem and -srid for the Database -d as a dem.xyz file -import_xyz import another .xyz file into a Dem-Database created with -create_dem these points will not be sorted, but added to the end =========================== Sample =========================== --> with 'SPATIALITE_DEM' set: spatialite_dem -fetchz_xy 24700.55278283251 20674.74537357586 33.5600000 ============================================================== |
Back to main SpatiaLite-Tools Wiki page