blog.itcode.devblog.itcode.dev

A Guide for Developers Traveling Through OpenLayers - 8. How to Request Geospatial Data. OGC

OpenLayers is a JavaScript library for providing maps or GIS services in a web browser. Among GIS libraries, it has the highest barrier to entry, but it offers correspondingly powerful features.

A Guide for Developers Traveling Through OpenLayers - 8. How to Request Geospatial Data. OGC

OpenLayers is a JavaScript library for providing maps or GIS services in a web browser. Among GIS libraries, it has the highest barrier to entry, but it offers correspondingly powerful features.
RWB0104
@RWBwritten at 2022-03-14 14:37:32
A Guide for Developers Traveling Through OpenLayers

시리즈 모아보기

A Guide for Developers Traveling Through OpenLayers

8 / 23

In the previous chapter, we built a geospatial data management system using GeoServer. Now all we need to do is properly call this data — but how should we go about it?

If each software or service provider had its own way of calling data, a lot of confusion would arise. Some services would offer a certain feature while others lacked it entirely — a frequent occurrence. In other words, this would undermine the consistency of the service. Given the complexity of geospatial data, the impact of broken consistency is even greater.

To solve this, the OGC standard was established. OGC (Open Geospatial Consortium) is an international standards organization that develops and implements open standards for geospatial technologies.

The OGC standard defines geospatial query standards. If software, web, or apps related to geospatial information comply with the OGC standard, they can receive data through the same request method regardless of form. In other words, if you use a system that complies with the OGC standard, you can maintain consistency across services. Once you learn it well, you can use it identically across every service that complies with the OGC standard. Because of this convenience, any legitimate GIS solution is sure to comply with the OGC standard.

Naturally, OGC standard compliance is not something you can simply claim — it must go through a review process that verifies the standard has been properly implemented before it can be said to comply with the OGC standard.


Below are the main items of the OGC standard in a web environment.

  • WFS (Web Feature Service): Attribute and spatial information of vector data
  • WMS (Web Map Service): Base maps and visualization
  • WCS (Web Coverage Service): Raster data extraction
  • WPS (Web Processing Service): Spatial analysis processing

WFS and WMS are used most frequently. This is because most services amount to simply querying geospatial data or calling up a base map.

Knowing just these two specs is enough to have no problems representing a map with OpenLayers.



The main commands of WFS are described below.

  • GetFeature
  • Transaction

The base URL looks like https://example.com/geoserver/wfs.


Calls the attribute information of a layer. In DB terms, this is the same as calling the data of a table.

Used when the attribute information of the map is needed.

The parameters required for GeoServer's GetFeature are as follows.

TXT

GET https://example.com/geoserver/wfs?service=WFS&version=2.0.0&request=GetFeature&typename=test:building&srsName=EPSG:3857&outputFormat=application/json&bbox=14168809.936013725,4366042.924151548,14170735.193663657,4367768.7289308,EPSG:3857
ParameterExampleRequireDescription
serviceWFS (fixed)YService name
version2.0.0 (default), 1.1.0, 1.0.0YVersion
requestGetFeature (fixed)YRequest name
typenamerepo_name:layer_nameYLayer name (multiple separated by commas)
srsNameEPSG:4326Base coordinate system (if left empty, the layer's default coordinate system is used)
outputFormatapplication/vnd.ogc.se_xml (default)Response format
exceptionsapplication/vnd.ogc.se_xml (default)Exception response format
propertyNameAll columnsColumn names to include in the response (multiple separated by commas)
bboxxmin,ymin,xmax,ymaxx_{min},y_{min},x_{max},y_{max},EPSG:0000Range to limit to
featureID{id}Feature ID

If you enter only the required parameters, it will retrieve the attribute information for all data in the target layer.


If you enter the desired EPSG code in srsName, it performs coordinate transformation accordingly and outputs the result. You don't need to worry at all about coordinate transformation on the client or server side.

If you want JSON format, specify application/json for outputFormat.


If you enter a column name in propertyName, only that data will be retrieved. By using this appropriately, you can call only the data you need to optimize response speed and size.


Only one of bbox or featureID can be used at a time. If you call WFS without any restrictions, it computes and responds with all the data in the layer, which takes a lot of time and puts a heavy load on the server. For this reason, most requests are limited to return only data corresponding to the current area. The area-limiting value used here is bbox.

The final EPSG code of bbox can be omitted, and if omitted, it is recognized and calculated as the layer's default EPSG coordinate system.


featureID targets and returns only a single piece of data with a specific ID. By default, every piece of data is assigned an ID, in the form {layer}.{number}. For example, if the layer name is test_layer, it would be test_layer.354.

If you make a request including featureID=354, only that single piece of data is returned.

TXT

/geoserver/wfs?service=WFS&version=2.0.0&request=GetFeature&typename=TEST:buld_sejong&srsName=EPSG:3857&outputFormat=application/json&exceptions=application/json&featureID=11645

JSON

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "id": "buld_sejong.11645",
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            1.418136757571567E7,
                            4370012.19281353
                        ],
                        [
                            1.418136633370244E7,
                            4370021.40639941
                        ],
                        [
                            1.418138830051506E7,
                            4370022.60152291
                        ],
                        [
                            1.418138868963238E7,
                            4370013.39142052
                        ],
                        [
                            1.418136757571567E7,
                            4370012.19281353
                        ]
                    ]
                ]
            },
            "geometry_name": "SHAPE",
            "properties": {
                "bdtyp_cd": "17005",
                "bd_mgt_sn": "3611033027102590003000005",
                "bsi_int_sn": 67897,
                "bsi_zon_no": "30078",
                "buld_mnnm": 35,
                "buld_nm": null,
                "buld_nm_dc": "4동",
                "buld_se_cd": "0",
                "buld_slno": 35,
                "bul_dpn_se": "M",
                "bul_eng_nm": null,
                "bul_man_no": 55809,
                "emd_cd": "330",
                "eqb_man_sn": 0,
                "gro_flo_co": 1,
                "li_cd": "27",
                "lnbr_mnnm": 259,
                "lnbr_slno": 6,
                "mntn_yn": "0",
                "mvmn_de": "20210308",
                "mvmn_resn": "건물번호 변경신청(노호리 259-6)에 따른 건물군 분리",
                "mvm_res_cd": "35",
                "ntfc_de": "20210308",
                "opert_de": "20210308130538",
                "pos_bul_nm": null,
                "rds_man_no": 3020,
                "rds_sig_cd": "36110",
                "rn_cd": "3258065",
                "sig_cd": "36110",
                "und_flo_co": 0
            }
        }
    ],
    "totalFeatures": 1,
    "numberMatched": 1,
    "numberReturned": 1,
    "timeStamp": "2022-03-10T16:05:54.511Z",
    "crs": {
        "type": "name",
        "properties": {
            "name": "urn:ogc:def:crs:EPSG::3857"
        }
    }
}

The above response is the result of calling GetFeature for the data whose ID is 11645 among buildings in Sejong City. Since outputFormat is specified as application/json, GeoJSON is returned as the response. If the response format is not specified, it responds in XML form.

If you added the parameter propertyName=bdtyp_cd,bd_mgt_sn, only bdtyp_cd and bd_mgt_sn would be included in properties.


Provides insert, update, and delete functionality for a layer's data.

The request method is POST across the board. Insert, update, and delete all use POST.

The operation is composed as XML in the body of the request. Because the OGC standard has been established for so long, most requests are XML-based by default.


The coordinate values of geospatial data can be defined by describing coordinates through a fixed XML format. The XML corresponding to each data type is as follows.

This XML is used for Transaction Insert and Update.

  • Polygon

XML

<gml:Polygon srsName="EPSG:0000">
	<gml:outerBoundaryIs>
		<gml:LinearRing>
			<gml:coordinates>x1,y1 x2,y2 x3,y3 x4,y4 x1,y1</gml:coordinates>
		</gml:LinearRing>
	</gml:outerBoundaryIs>
</gml:Polygon>

The coordinate system is described in the srsName attribute of gml:Polygon. If omitted, it is recognized as the default coordinate system of the target layer.

Coordinates are described inside gml:coordinates. A single coordinate x,yx, y is separated by a comma, and each coordinate is separated from the next by a space.

Remember that for a Polygon, the first coordinate and the last coordinate must always be identical.

  • Line

XML

<gml:LineString srsName="EPSG:0000">
	<gml:coordinates>x1,y1 x2,y2 x3,y3 x4,y4</gml:coordinates>
</gml:LineString>

The coordinate system is described in the srsName attribute of gml:LineString. If omitted, it is recognized as the default coordinate system of the target layer.

Coordinates are described inside gml:coordinates. A single coordinate x,yx, y is separated by a comma, and each coordinate is separated from the next by a space.

Remember that for a Line, the first coordinate and the last coordinate must always differ.

  • Point

XML

<gml:Point srsName="EPSG:0000">
	<gml:coordinates>x,y</gml:coordinates>
</gml:Point>

The coordinate system is described in the srsName attribute of gml:Point. If omitted, it is recognized as the default coordinate system of the target layer.

Coordinates are described inside gml:coordinates. Since it is a point, only x,yx, y exist, and the two are separated by a comma.


A function for inserting layer data.

TXT

POST https://example.com/geoserver/wfs

XML

<wfs:Transaction
	xmlns:wfs="http://www.opengis.net/wfs"
	xmlns:gml="http://www.opengis.net/gml"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	service="WFS"
	version="1.0.0"
	xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd">
	<wfs:Insert>
		<layer_name>
			<column1>value1</column1>
			<column2>value2</column2>
			<column3>value3</column3>
			<geo_column>
				<gml:Polygon srsName="EPSG:4326">
					<gml:outerBoundaryIs>
						<gml:LinearRing>
							<gml:coordinates>x1,y1 x2,y2 x3,y3 x4,y4 x1,y1</gml:coordinates>
						</gml:LinearRing>
					</gml:outerBoundaryIs>
				</gml:Polygon>
			</geo_column>
		</layer_name>
	</wfs:Insert>
</wfs:Transaction>

The above XML adds a Polygon. Interpreting this XML gives us the following.

  • The target table is layer_name.
  • Insert value1, value2, value3 into columns column1, column2, column3 respectively.
    • If a column exists in the schema but is not specified during insertion, that column is inserted as null.
  • The name of the geospatial column is geo_column.
  • It is a polygon with coordinates x1,y1 x2,y2 x3,y3 x4,y4 x1,y1.
    • The coordinate system is EPSG:4326.

Change the table name, columns, and so on to fit your use case.

XML

<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse
	xmlns:wfs="http://www.opengis.net/wfs"
	xmlns:ogc="http://www.opengis.net/ogc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	version="1.0.0"
	xsi:schemaLocation="http://www.opengis.net/wfs https://api.itcode.dev/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
	<wfs:InsertResult>
		<ogc:FeatureId fid="buld_test.71"/>
	</wfs:InsertResult>
	<wfs:TransactionResult>
		<wfs:Status>
			<wfs:SUCCESS/>
		</wfs:Status>
	</wfs:TransactionResult>
</wfs:WFS_TransactionResponse>

A normal response looks like the above. Unfortunately, the Transaction response only supports XML.

The information we can obtain from the above response is as follows.

  • Data was inserted
  • The response result is SUCCESS, meaning success
  • The ID of the created object is buld_test.71

A function for modifying layer data.

TXT

POST https://example.com/geoserver/wfs

XML

<wfs:Transaction
	xmlns:wfs="http://www.opengis.net/wfs"
	xmlns:gml="http://www.opengis.net/gml"
	xmlns:ogc="http://www.opengis.net/ogc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	service="WFS"
	version="1.0.0"
	xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd">
	<wfs:Update typeName="layer_name">
		<wfs:Property>
			<wfs:Name>column1</wfs:Name>
			<wfs:Value>value1</wfs:Value>
		</wfs:Property>

		<wfs:Property>
			<wfs:Name>column2</wfs:Name>
			<wfs:Value>value2</wfs:Value>
		</wfs:Property>

		<wfs:Property>
			<wfs:Name>geo_column</wfs:Name>
			<wfs:Value>
				<gml:Polygon srsName="EPSG:0000">
					<gml:outerBoundaryIs>
						<gml:LinearRing>
							<gml:coordinates>x1,y1 x2,y2 x3,y3 x4,y4 x1,y1</gml:coordinates>
						</gml:LinearRing>
					</gml:outerBoundaryIs>
				</gml:Polygon>
			</wfs:Value>
		</wfs:Property>

		<ogc:Filter>
			<ogc:FeatureId fid="layer_name.32" />
		</ogc:Filter>
	</wfs:Update>
</wfs:Transaction>

The above XML modifies a Polygon. Interpreting this XML gives us the following.

  • The target table is layer_name.
  • Change columns column1, column2 to value1, value2 respectively.
    • Each column is wrapped in wfs:Property.
    • Only the specified columns are changed.
  • The name of the geospatial column is geo_column.
  • It is changed to a polygon with coordinates x1,y1 x2,y2 x3,y3 x4,y4 x1,y1.
    • The coordinate system is EPSG:4326.
  • The target object to change is the object whose ID is layer_name.32.

Change the table name, columns, and so on to fit your use case.

ogc:Filter follows the OGC Filter format.

The above XML changed only a single piece of data whose ID is layer_name.32, but depending on the composition of the filter, multiple pieces of data can be changed all at once.

The OGC Filter related to this will be described later.

XML

<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse
	xmlns:wfs="http://www.opengis.net/wfs"
	xmlns:ogc="http://www.opengis.net/ogc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	version="1.0.0"
	xsi:schemaLocation="http://www.opengis.net/wfs https://api.itcode.dev/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
	<wfs:InsertResult>
		<ogc:FeatureId fid="none"/>
	</wfs:InsertResult>
	<wfs:TransactionResult>
		<wfs:Status>
			<wfs:SUCCESS/>
		</wfs:Status>
	</wfs:TransactionResult>
</wfs:WFS_TransactionResponse>

A normal response looks like the above. The information we can obtain from the above response is as follows.

  • Data was updated
    • The form is identical to insertion via InsertResult, but since nothing new was created, the ID is none.
  • The response result is SUCCESS, meaning success

A function for deleting layer data.

Since only a simple deletion needs to be performed, the XML is much simpler.

TXT

POST https://example.com/geoserver/wfs

XML

<wfs:Transaction
	xmlns:wfs="http://www.opengis.net/wfs"
	xmlns:ogc="http://www.opengis.net/ogc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	service="WFS"
	version="1.0.0"
	xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd">
	<wfs:Delete typeName="layer_name">
		<ogc:Filter>
			<ogc:FeatureId fid="layer_name.66" />
		</ogc:Filter>
	</wfs:Delete>
</wfs:Transaction>

The above XML deletes a Polygon. Interpreting this XML gives us the following.

  • The target table is layer_name.
  • The object to delete is the object whose ID is layer_name.66.

Since all it needs to do is delete data, the XML is much simpler than the other APIs. This is because you only need to target which object is to be deleted.+

Likewise, depending on the composition of the filter, multiple pieces of data can be deleted all at once.

The OGC Filter related to this will be described later.

XML

<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse
	xmlns:wfs="http://www.opengis.net/wfs"
	xmlns:ogc="http://www.opengis.net/ogc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	version="1.0.0"
	xsi:schemaLocation="http://www.opengis.net/wfs https://api.itcode.dev/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
	<wfs:InsertResult>
		<ogc:FeatureId fid="none"/>
	</wfs:InsertResult>
	<wfs:TransactionResult>
		<wfs:Status>
			<wfs:SUCCESS/>
		</wfs:Status>
	</wfs:TransactionResult>
</wfs:WFS_TransactionResponse>

A normal response looks like the above. The information we can obtain from the above response is as follows.

  • Data was deleted
    • The form is identical to insertion via InsertResult, but since nothing was newly deleted, the ID is none.
    • It is hard to distinguish between an update and a deletion.
  • The response result is SUCCESS, meaning success


The main commands of WMS are described below.

  • GetMap
  • GetFeatureInfo

The base URL looks like https://example.com/geoserver/wms.


Provides a map rendered based on a layer's data and declared style. In other words, it provides an image such as a PNG, not text-based data such as JSON.

Based on the data you hold, you can also provide a map designed by yourself.

The parameters required for GeoServer's GetMap are as follows.

TXT

GET https://example.com/geoserver/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&layers=buld_sejong&exceptions=application%2Fjson&WIDTH=256&HEIGHT=256&CRS=EPSG%3A3857&STYLES=&BBOX=14167144.570487704%2C4365471.559422987%2C14167756.066713985%2C4366083.055649268
ParameterExampleRequireDescription
serviceWMS (fixed)YService name
version1.3.0 (fixed), 1.1.1, 1.1.0, 1.0.0YVersion
requestGetMap (fixed)YRequest name
layersrepo_name:layer_nameYLayer name (multiple separated by commas)
stylesstyle1Name of the style to apply (if left empty, the default style set in GeoServer is applied; multiple separated by commas)
srs(or crs)EPSG:4326Base coordinate system (if left empty, recognized as the layer's default coordinate system)
bboxxmin,ymin,xmax,ymaxx_{min},y_{min},x_{max},y_{max}YImage area coordinates
width256YImage width
height256YImage height
formatimage/pngYRequest name
transparentfalse (default)Whether the background is transparent
bgcolorFFFFFF (default)Background color in RRGGBB form
exceptionsapplication/vnd.ogc.se_xml (default)Exception response format
time2022-03-14T22:30.27.520+09:00Time for time-series data (yyyy-MM-ddThh:mm:ss.SSSZ)
sldhttps://example.com/sld.xmlXML file path
sld_bodySLD XML

WMS is unusual among OGC standard commands in that it returns an image. You can confirm that format is also an image MIME type. Through this, you can also serve a map designed by yourself.

However, rendering time can become longer as the number of layers grows or the SLD becomes more complex.


srs is the base coordinate system. You enter the EPSG code of the bbox, and if left empty, it is recognized as the layer's default EPSG code.

If version is 1.3.0, use crs instead.


WMS must always have an area entered via bbox.


styles is the name of the SLD to use. In GeoServer, you can designate the SLD to use for that layer, and this is where you enter the name of the designated SLD.

You can enter one or more SLDs separated by commas, and if left empty, the default designated SLD is automatically selected.


time is a parameter for time-series data. If there is data separated by time, it can be called through this parameter.


sld is a parameter for specifying an external SLD, into which you enter a URL.

sld_body is for entering the SLD XML directly into the parameter.

This is an example response of GetMap.


Since the map output by GetMap turns every object into an image, it seems impossible to select or identify objects.

However, using GetFeatureInfo, you can check the information of an object when you click on the image.

The parameters required for GeoServer's GetFeatureInfo are as follows.

TXT

GET https://example.com/geoserver/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetFeatureInfo&FORMAT=image%2Fpng&TRANSPARENT=true&QUERY_LAYERS=buld_sejong&layers=buld_sejong&exceptions=application%2Fjson&INFO_FORMAT=application%2Fjson&I=221&J=178&WIDTH=256&HEIGHT=256&CRS=EPSG%3A3857&STYLES=&BBOX=14169590.555392835%2C4366694.551875548%2C14169896.303505976%2C4367000.299988689
ParameterExampleRequireDescription
serviceWMS (fixed)YService name
version1.3.0 (fixed), 1.1.1, 1.1.0, 1.0.0YVersion
requestGetFeatureInfo (fixed)YRequest name
layersrepo_name:layer_nameYLayer name (multiple separated by commas)
stylesstyle1Name of style to apply (has no meaning in GetFeatureInfo)
crs(or srs)EPSG:4326Base coordinate system (if left empty, recognized as the layer's default coordinate system)
bboxxmin,ymin,xmax,ymaxx_{min},y_{min},x_{max},y_{max}YImage area coordinates
width256YImage width
height256YImage height
query_layersrepo_name:layer_nameYNames of additional requested layers (multiple separated by commas)
info_formatapplication/vnd.ogc.se_xml (default)Response format
feature_count1 (default)Maximum number of objects to call
x(or i)225Yx pixel value of the map
y(or j)156Yy pixel value of the map
exceptionsapplication/vnd.ogc.se_xml (default)Exception response format

layers and query_layers can be confusing because they look similar, but this is because it was designed with expansion of GetMap in mind.

They are kept separate so that you can simply append the few extra parameters GetFeatureInfo additionally requires to a GetMap request. The difference between layers and query_layers is as follows.

  • layers: When calling GetMap, the corresponding layer is displayed on the map
  • query_layers: Not displayed by GetMap, but included and searched in GetFeatureInfo

This is also the reason why the response format parameter for all the commands introduced so far has been format, whereas only GetFeatureInfo uses the different name info_format.


Since GetFeatureInfo is a command that calculates the clicked location and outputs the information of the corresponding object, the value entered in info_format uses a text MIME type just like GetFeature.


x, y are the pixel values where the mouse was clicked on the map. Be careful — these are not coordinates. Coordinates are entered in bbox.

If version is 1.3.0, you must use i, j instead of x, y.



The commands introduced above are the most frequently used commands among the OGC standard, and there are many other varied commands beyond these that may well be essential to you.

As with the examples explained going forward, a map with basic functionality can be sufficiently serviced by appropriately using just the functions above.

If you'd like to know more, check here.

# GIS# GeoServer
ship
blog.itcode.dev

Notes from the π-th Alpaca

7.0.1
Developed by RWB since 2021.057th upgraded at 2026.08