-
Notifications
You must be signed in to change notification settings - Fork 0
dft street manager spike 0003 mapping data
- Used by Land Registry to draw LA boundary lines, deployment and configuration issues
The local authority boundaries are available from Ordnance Survey OpenData: https://www.ordnancesurvey.co.uk/opendatadownload/products.html#BDLINE
The shape file called 'district_borough_unitary_region' will show the correct boundary information.
This shape file is in the projection ESPG:27700 and will need to be converted to the same projection as before being deployed to mapserver.
The ms4w windows utility can be used to convert maps to different projections. (See: https://ms4w.com/)
The following command with convert the shape file to the required projection:
ogr2ogr -t_srs WGS84 <<path_to_file>>\district_borough_unitary_region_output.shp <<path_to_file>>\district_borough_unitary_region.shp
The displaying of local boundaries was discussed in the Show & Tell for Sprint 2 and decided that it was not required to be displayed on the map.
The following investigation was completed using mapserver as a docker container. (See. https://github.com/kartoza/docker-mapserver)
The following docker command was used to run the server:
docker run --name map -d -p 8182:80 -v <<volume_path>>/map:/map mapserver
The converted shape files should be placed in a directory under <<volume_path>>/map
An example map file used to to serve the boundaries can be seen here.
When this is added as a layer to OpenLayersMap the result looks like the below:
The following integration was completed using Postgres with Postgis extensions as a docker container. (See: https://hub.docker.com/r/mdillon/postgis/)
The following command is used to start the postgis instance:
docker run --name some-postgis -e POSTGRES_PASSWORD=postgres -e ALLOW_IP_RANGE=0.0.0.0/0 -p 5432:5432 -v <<volume_path>>/map:/map -d mdillon/postgis
And the below command used to connect to the running instance:
docker exec -i -t some-postgis /bin/bash
Geometry entries can be saved in postgis in order to be rendered by a mapping server. The below steps show how to insert a mapserver shape file so it can be read from postgis.
createdb -h "$POSTGRES_PORT_5432_TCP_ADDR" -p "$POSTGRES_PORT_5432_TCP_PORT" -U postgres -T template_postgis shape
The above command creates a database called shape using the supplied postgis template.
shp2pgsql -I -s 4326 <<shape_file>> districts | psql -h "$POSTGRES_PORT_5432_TCP_ADDR" -p "$POSTGRES_PORT_5432_TCP_PORT -U postgres -d shape
The shp2pgsql command is used to create the sql to insert a shape file into a new table called 'districts' using the given projection 4326. The output is then piped to a psql command to execute the updates. This can also be done with an intermediary sql file:
shp2pgsql -I -s 4326 /map/counties/dbur_84.shp districts > SHAPEFILE.sql'
psql -h "$POSTGRES_PORT_5432_TCP_ADDR" -U postgres -p "$POSTGRES_PORT_5432_TCP_PORT" -d shape -f SHAPEFILE.sql
Mapserver can then be configured to read the shape file and render it as a map layer. The following lines in the map file indicate the data is being retrieved from postgis, configure the connection and set the data parameters:
CONNECTIONTYPE POSTGIS
CONNECTION "host=192.168.99.100 dbname=shape user=postgres password=postgres port=5432"
DATA "geom from districts"
An example of a map file connecting to postgis can be found here.
Areas drawn on a map can be written back to postgis to be saved and rendered back through mapserver.
The below sql command will create a table in the postgis database called drawn_polygon:
CREATE TABLE drawn_polygon ( p_id INTEGER PRIMARY KEY );
Postgis contains a command for adding a geometry column to the table:
SELECT AddGeometryColumn('drawn_polygon','the_geom','3857','POLYGON',2);
This command adds a new column to the drawn_polygon table indicating the type of shape (POLYGON) and the projection of the shape (3857).
To insert a row into this table the following command:
INSERT INTO drawn_polygon(p_id, the_geom) VALUES(1, ST_GeomFromText(?, 3857));
This command will use convert a textual representation of a polygon into a postgis geometry column. The value of the text can be returned from open layers with the following commands:
var writer = new ol.format.WKT()
var geomWKT = writer.writeGeometry(event.feature.getGeometry())
This will generate text in the format: POLYGON((19004.239492803947 6776142.885363474,19057.984278316962 6775892.076364413,19097.397121026508 6775902.825321515,19036.486364111755 6776154.828649143,19004.239492803947 6776142.885363474))
This can be used as the parameter in the ST_GeomFromText command.
To render this back on a map, another layer should be added in the map file:
CONNECTIONTYPE POSTGIS
CONNECTION "host=192.168.99.100 dbname=shape user=postgres password=postgres port=5432"
DATA "the_geom from drawn_polygon"
The attached map file also contains this example here.
To server a shape file as a WFS layer from MapServer the following needs to be configured in the WEB section of a map file:
METADATA
"wfs_title" "Counties WFS"
"wfs_onlineresource" "http://127.0.0.1/cgi-bin/mapserv.exe?map=C:/ms4w/apps/map/counties-postgis-wfs.map&"
"wfs_crs" "EPSG:4326 ESPG:3857"
"wfs_enable_request" "*"
END
The above will specify that the map is to be made available as a Web Feature Service layer. An example of a map configured to serve WFS feature layers can viewed here.
By default the features will be returned in GML format. To allow features to be returned in GeoJSON format, then the following lines need to be added to the mapfile:
OUTPUTFORMAT <br/>
NAME "geojson" <br/>
DRIVER "OGR/GEOJSON" <br/>
MIMETYPE "application/json; subtype=geojson" <br/>
FORMATOPTION "STORAGE=stream" <br/>
FORMATOPTION "FORM=SIMPLE" <br/>
END
In the layer or application metadata the following line should be added:
"wfs_getfeature_formatlist” "geojson"
Open Layers can also render GeoJSON features on a map. See the below code fragment for details:
var featureRequest = new ol.format.WFS().writeGetFeature({
srsName: 'EPSG:3857',
featureNS: 'http://mapserver.gis.umn.edu/mapserver',
featurePrefix: 'ms',
featureTypes: ['drawn_features'],
outputFormat: 'geojson',
filter: ol.format.filter.equalTo('works_owner', worksOwner)
})
// then post the request and add the received features to a layer
fetch('http://127.0.0.1/cgi-bin/mapserv.exe?map=C:/ms4w/apps/map/counties-postgis-wfs.map&SERVICE=WFS', {
method: 'POST',
body: new XMLSerializer().serializeToString(featureRequest)
}).then(function (response) {
return response.json();
}).then(function (json) {
var features = new ol.format.GeoJSON().readFeatures(json);
MAP_CONFIG.vector_source.clear()
MAP_CONFIG.vector_source.addFeatures(features);
});
MapServer does provide the ability to filter features shown on the map. This is done by providing a Filter in XML format to the URL request. e.g.
http://demo.mapserver.org/cgi-bin/wfs?&VERSION=1.0.0&SERVICE=WFS
&REQUEST=GetFeature&TYPENAME=cities&Filter=<Filter>
<PropertyIsEqualTo><PropertyName>NAME</PropertyName>
<Literal>Halifax</Literal></PropertyIsEqualTo></Filter>
- How do we serve works mapping information so that external tools can access it?
- Source of mapping information? (OS Mastermap etc.
- WMTS provider (ourselves/provider)
- Do we need to display local authority boundary information?
- How do we serve large volumes of works data on maps without crowding?
- How do we filter works data by date?