Getting Started With OpenLayers 3 And Spatial Data

Recently, I got an opportunity to work with OpenLayers and thought it worth sharing. In this article, I am going to give you a jump start to visualize spatial data using OpenLayers. In the demo, I will be using SQL Server 2008 and OpenLayers 3.

Before starting work with OpenLayers and spatial data, let me explain these two buzzwords in short so that you can jump-start.

OpenLayers

It’s an open-source project for all your mapping needs, which is being updated frequently by its community, and their (developer) work is appreciated to bring all GIS mapping needs tour.

It provides tiles and vector layers so that we can work with existing GIS servers and map providers like Google and Bing Maps. Using vector layer we can add any geometry in the map (which may exist in SQL Server, ORACLE, or other databases that support Spatial data types).

Since it's open source you can customize and implement it as per your need. However, it provides great flexibility to extend its features.

You can read more about OpenLayers.

Spatial Data types

Definition from MSDN: There are two types of spatial data. The geometry data type supports planar, or Euclidean (flat-earth), data. The geometry data type conforms to the Open Geospatial Consortium (OGC) Simple Features for SQL Specification version 1.1.0 and is compliant with SQL MM (ISO standard).

In addition, SQL Server supports the geography data type, which stores ellipsoidal (round-earth) data, such as GPS latitude and longitude coordinates.

Types of spatial data

There are 2 types of spatial data

  1. Represent geometry in 2 dimensions
  2. Another is geography which is an ellipsoidal representation of data.

Here is how we differentiate those.

Geography

Courtesy: simple-talk.com

It is a vast topic to describe here, but you can read more on MSDN.

Now in this article, I will explain how you can visualize your raw spatial data on a map using openlayer3.

In this demo I will be using SQL Server 2008 and OpenLayers 3, from SQL Server 2008 there is support for spatial data types. Here is my table for this demo:

Geometry

As you can see I can choose either geography or geometry. For jump start, I will be using a simple geometry type. Geometry includes different types, as below

Types of geometry

Courtesy: msdn.microsoft.com

So we can use any of the following.

  • Point
  • LineString
  • Polygon
  • Multipolygon
  • MultilineString
  • Multipoint

In this demo, we will be working with Point, LineString, and Polygon and see the results on a map.

Note. While working on Spatial data SRID (which represents Spatial Reference Systems) is important.

As per Wikipedia “A spatial reference system (SRS) or coordinate reference system(CRS) is a coordinate-based local, regional or global system used to locate geographical entities. A spatial reference system defines a specific map projection, as well as transformations between different spatial reference systems.”

Note. I am not going to use SRID for this example as it is not required in the current scenario but while working with a real application you must consider the same.

Step 1. Create a simple table in SQL as above screen. The table name is TEST_SPATIAL (script attached).

Step 2. Now we will insert some spatial data in a table.

Since SQL Server has a lot of functions to work with Spatial data, I am going to use the STGeomFromText function to get spatial data from text format(known as WKT(well-known text))

Inserting spatial data

Inserting point

DECLARE @data nvarchar(max) = 'POINT (1 10)'; -- Point
DECLARE @g geometry;
SET @g = geometry::STGeomFromText(@data, 0);
INSERT INTO dbo.TEST_SPATIAL
VALUES (@g)

Same as we can insert LineString as ‘LINESTRING (4 4 4 4, 9 0 4 4)’ and Polygon as ‘POLYGON ((0 0, 30 0, 30 30, 0 30, 0 0))’.

Now you will see your spatial data in binary format as below.

Spatila

You can also see the spatial result view.

Spaial result

Step 3. Now we have our spatial data ready. To place data on a map, .NET fretwork provides a library of Microsoft.SqlServer.Types to work with, which is the same library we are using in SQL (using common language runtime).

The purpose of this library is to manipulate and work with Spatial data in CLR-compatible language like C#. Since we just want to represent our data in the map without any manipulation we will not use this for now.

Referencing OpenLayers3 in ASP.NET project

To reference OpenLayers3 in any ASP.NET website (or web application) we just require the following files:

  1. ol.js: This file contains the core of OpenLayers.
  2. ol.css: This file contains styles for maps.

You can find those files on the OpenLayers website or reference, where the debug file is for development purposes.

I would also like to mention that there are helper libraries Proj4.js for the front end, and proj4net for the back end (.net), which can make your GIS development easy.

For this demonstration, I am not going to use any of the above as I will be using a smart feature of OpenLayers which is now available in openlayer3. With the help of this, we can read WKT(well-known text) from the database. STAsText() function provides a twetwkt format of a geometry.

Here is my simple function to query spatial data from SQL in wkt.

public List<string> GetSpatialData()
{
    List<string> spatialDataList = new List<string>();
    dbConnection.Open();
    var command = new SqlCommand("select [GEOMETRY].STAsText() from TEST_SPATIAL where GEOMETRY IS NOT NULL", dbConnection);
    var rdr = command.ExecuteReader();
    while (rdr.Read())
    {
        spatialDataList.Add(Convert.ToString(rdr[0]));
    }
    dbConnection.Close();
    return spatialDataList;
}

In the Default.aspx page First of all we require a map object as follows.

var map = new ol.Map({
    layers: [layer],
    target: 'map',
    view: new ol.View({
        center: [0, 0],
        zoom: 2
    })
});

This is the base object of the map to be rendered. There are 3 key layers, target, view.

  • Layer: In laymen's terms layer is another map rendering on an existing map, which may contain geometries/objects to be displayed on the map.
  • Target: This is an HTML dom element ID in which the map will be rendered.
  • View: This defines the initial position of the map and its zoom level.

Apart from the above, several configurations are not required in this demonstration. As there any many types of layers, I will use OSM (open street map) and Vector layer. We use the Vector layer when we need to display geometries from our database.

We create an object of the OSM layer as follows.

var osmLayer = new ol.layer.Tile({
    source: new ol.source.OSM()
});

And will pass the osmLayer object to map layer key as.

var map = new ol.Map({
    layers: [osmLayer],
    target: 'map',
    view: new ol.View({
        center: [0, 0],
        zoom: 2
    })
});

And here is the output.

Output

The next step is to add SQL spatial geometries to the map. There are no ways to render spatial data in openlayer3, we can use JSON objects, we can manually create features (explained below), and add them on the map, or can read with formatted geometry (which we are going to see).

Features are the objects we see on the map layer. The feature can be a line, or polygon point. To visualize those features we use style to add color to these geometries.

To visualize spatial data on a map, first of all, we will put all geometries in a JavaScript array for simplicity.

var geometries = []; // javascript array
<% GettingStarted.GeoHelper helper = new GettingStarted.GeoHelper();
foreach (var item in helper.GetSpatialData())
{ %>
    geometries.push('<%=item %>');
<% } %>

Now will create an object of wkt parser/formatter/reader and will create an array of features.

var wktReader = new ol.format.WKT();
var featureCollection = []; // features to render on map

To visualize features on the map we need to apply styling on features as per geometry type.

for (var i = 0; i < geometries.length; i++)
{
    var feature = wktReader.readFeature(geometries[i]);
    feature.getGeometry().transform('EPSG:4326', 'EPSG:3857');
    if (feature.getGeometry().getType() == 'Polygon')
    {
        feature.setStyle(new ol.style.Style(
        {
            stroke: new ol.style.Stroke(
            {
                color: 'blue',
                width: 3
            }),
            fill: new ol.style.Fill(
            {
                color: 'rgba(0, 0, 255, 0.1)'
            })
        }));
        featureCollection.push(feature);
    }
    else if (feature.getGeometry().getType() == 'LineString')
    {
        feature.setStyle(new ol.style.Style(
        {
            stroke: new ol.style.Stroke(
            {
                color: 'red',
                width: 3
            })
        }));
        featureCollection.push(feature);
    }
    else if (feature.getGeometry().getType() == 'Point')
    {
        feature.setStyle(new ol.style.Style(
        {
            image: new ol.style.Icon(
            {
                anchor: [0.5, 46],
                anchorXUnits: 'fraction',
                anchorYUnits: 'pixels',
                opacity: 0.75,
                src: 'Icons/marker.png'
            })
        }));
        featureCollection.push(feature);
    }
}

We use a feature.setStyle(style) function to apply style. Also, note we must transform all geometries to map transformation( projection).

transform('EPSG:4326', 'EPSG:3857');

Which we configure using SRID in the database (as mentioned earlier).

Since we are having 3 types of geometries we have applied style accordingly. You can use any styling as per your requirement.

Now we will create a Vector source using the source object and add featureCollection.

var source = new ol.source.Vector({
    features: featureCollection
});

Create a layer using a layer object and add a source to it.

var vectorLayer = new ol.layer.Vector({
    source: source
});

And at last, add a layer to map the object.

var map = new ol.Map({
    layers: [osmLayer, vectorLayer],
    target: 'map',
    view: new ol.View({
        center: [0, 0],
        zoom: 2
    })
});

Output

Specify regions

I would try to create specific geometry for a region but it’s a bit difficult to create coordinates for complex geometries.

Final Words, This was just a jump-start demo with OpenLayers and Spatial data. For further reading you can visit OpenLayers.org where you can find API docs and source code, you can consider MSDN for Spatial data types.

Your ideas and suggestions will be appreciated.

Update

Source code uploaded.

Read more articles on Spatial Data.


Similar Articles