From charlesreid1

No edit summary
 
(21 intermediate revisions by the same user not shown)
Line 1: Line 1:
This guide picks up where the [[Geodroplet]] page left off:
My Geodroplet adventure:
 
* Part 1 - [[Geodroplet]]
* Part 2 - this page
* Part 3 - [[Geoserver OilGas]]


http://docs.geoserver.org/stable/en/user/gettingstarted/web-admin-quickstart/index.html
http://docs.geoserver.org/stable/en/user/gettingstarted/web-admin-quickstart/index.html
Line 25: Line 29:
There's also "Layers," "Workspaces," etc. Not clear what all of this is for, I'm just browsing through it... Geoserver documentation isn't saying much about what these things are. (This is the web interface quick start, after all...)
There's also "Layers," "Workspaces," etc. Not clear what all of this is for, I'm just browsing through it... Geoserver documentation isn't saying much about what these things are. (This is the web interface quick start, after all...)


==Tutorial==
=Tutorial=


Here is a tutorial: http://docs.geoserver.org/stable/en/user/gettingstarted/shapefile-quickstart/index.html
Here is a tutorial: http://docs.geoserver.org/stable/en/user/gettingstarted/shapefile-quickstart/index.html


===Importing Shape Data===
==Importing Shape Data==


Download the NYC roads shape file package linked to in the tutorial.
Download the NYC roads shape file package linked to in the tutorial.
Line 49: Line 53:
Now we keep following the instructions.
Now we keep following the instructions.


===Creating Workspace===
==Creating Workspace==


Still logged into the Geoserver web portal as the admin, we go to Data and Workspaces, on the left hand side menu.
Still logged into the Geoserver web portal as the admin, we go to Data and Workspaces, on the left hand side menu.
Line 55: Line 59:
We pick add a new workspace, name it and populate it following the tutorial instructions [http://docs.geoserver.org/stable/en/user/gettingstarted/shapefile-quickstart/index.html].
We pick add a new workspace, name it and populate it following the tutorial instructions [http://docs.geoserver.org/stable/en/user/gettingstarted/shapefile-quickstart/index.html].


===Creating Store===
==Creating Store==


Followed the tutorial instructions to create a store for NYC roads data...
Followed the tutorial instructions to create a store for NYC roads data...


===Creating Layer===
==Creating Layer==


Created a layer for looking at that map... this is a lot of steps, making for a cumbersome workflow...
Created a layer for looking at that map... this is a lot of steps, making for a cumbersome workflow...
Line 66: Line 70:


[http://docs.geoserver.org/stable/en/user/gettingstarted/shapefile-quickstart/index.html]
[http://docs.geoserver.org/stable/en/user/gettingstarted/shapefile-quickstart/index.html]
=An Embedded Map with Data from Geoserver=
In order to test out the server's capabilities, I wanted to visualize the New York City streets dataset that I just imported in a site with an embedded map. For this purpose, I can use Leaflet, the Javascript maps app. I'll feed Leaflet a GeoJSON URL for the New York City street data, which Geoserver will serve up.
This will have three parts:
* HTML (and CSS)
* Javascript
* URL for GeoJSON data
==Before We Begin==
The first thing we have to do, in order to access GeoJSON data via a URL, is fix the security settings of Geoserver. Right now, it is only set to serve up data to requests from "localhost." We will be accessing it from its IP address (and potentially other IP addresses, if it is a public server).
The error I was seeing was:
<pre>
XMLHttpRequest cannot load http://AAA.BBB.CCC.DDD:8080/geoserver/nyc_roads/ows?service=WFS&version=1.0.…&typeName=nyc_roads:nyc_roads&maxFeatures=50&outputFormat=application/json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://AAA.BBB.CCC.DDD' is therefore not allowed access.
</pre>
===Setting Up a Proxy Pass===
Searching for this error yielded a stack overflow question that mentioned a Proxy Pass for Apache that needed to be set up [http://gis.stackexchange.com/questions/83272/geoserver-access-control-allow-origin]
The Geoserver tutorial states that to make requests from places other than "localhost", you have to set up an Apache proxy pass [http://www.gistutor.com/geoserver/21-intermediate-geoserver-tutorials/38-configuring-geoserver-proxy-for-public-and-remote-data-access.html]
This involved editing the apache configuration file, at <code>/etc/apache2/sites-available/000-default.conf</code> on default Apache installations on Ubuntu systems, and added the following just before the <code>VirtualHost *:80</code> tag:
<pre>
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /geoserver http://localhost:8080/geoserver
ProxyPassReverse /geoserver http://localhost:8080/geoserver
</pre>
In plain English: when an outside server accesses the <code>/geoserver</code> directory, it is passed through a local proxy.
What a local proxy does is take requests from non-local servers to access the Geoserver, and makes them look like local requests.
Note that you'll have to do this, even if you're accessing Geoserver from the same IP address and the same machine, as long as you don't access Geoserver using an address like localhost:8080.
===Enabling Apache Proxy Mod===
I had to take one more step, before this worked, since my Apache installation didn't have the Proxy module enabled by default.
I ran this command to enable the Proxy mod:
<pre>
sudo a2enmod proxy
</pre>
after which, I restarted apache:
<pre>
sudo service apache2 restart
</pre>
<!--
===Creating Proxy CGI File===
The example/tutorial mentions an OpenLayers CGI file that will act as a proxy. (Link: http://trac.osgeo.org/openlayers/browser/trunk/openlayers/examples/proxy.cgi)
This isn't useful, though, because it is for OpenLayers, and we are using Leaflet.
===Python CGI Script===
The tutorial links to a Python CGI script, which was actually for OpenLayers. I am using Leaflet.
But I enabled Apache CGI anyway.
<pre>
sudo a2enmod cgi
</pre>
This creates a directory for CGI scripts owned by root, at <code>/usr/lib/cgi-bin</code>.
-->
===Geoserver Use JSONP===
Following this page [http://gis.stackexchange.com/questions/57494/geoserver-2-3-how-to-enable-jsonp] I enabled JSONP by editing <code>/var/lib/tomcat7/webapps/geoserver/WEB-INF/web.xml</code> as sudo, and adding this block:
<pre>
  <context-param>
    <param-name>ENABLE_JSONP</param-name>
    <param-value>true</param-value>
  </context-param>
</pre>
Now, when I make a request to my Geoserver in my Javascript code, it will specify the format as JSONP. My javascript code will look like this:
<source lang="javascript">
var owsrootUrl = 'http://AA.BB.CC.DD:8080/geoserver/ows';
var defaultParameters = {
    service : 'WFS',
    version : '1.0',
    request : 'GetFeature',
    typeName : 'nyc_roads:nyc_roads',
    maxFeatures : '100',
    outputFormat : 'text/javascript',
    format_options : 'callback:getJson',
};
var parameters = L.Util.extend(defaultParameters);
var URL = owsrootUrl + L.Util.getParamString(parameters);
</source>
and when we use some ajax for the map features, it will look like:
<source lang="javascript">
$.ajax({
    type: "POST",
    url: URL,
    dataType: 'jsonp',
    jsonpCallback : 'getJson',
</source>
==Embedded Map Example Page==
The following files can be served up by a web server to serve up a map with Leaflet.
Right now, the embedded objects from Geoserver are not showing up, but when I print them in the browser's console they all seem to be intact.
===HTML: index.html===
<source lang="javascript">
<html>
<head>
    <title>Geodrop demo</title>
    <!-- load the leaflet library -->
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
    <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
    <!-- load my style sheet -->
    <link rel="stylesheet" type="text/css" href="style.css">
    <!-- load jquery -->
    <script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
    <script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
</head>
<body>
    <!-- create a map div -->
    <div id="map"></div>
</body>
    <script type="text/javascript" src="mymap.js"></script>
</html>
</source>
===CSS: style.css===
<source lang="javascript">
#map {
    height: 600px;
    width: 600px;
}
</source>
===Javascript: mymap.js===
<source lang="javascript">
// create the map, assign to the mao div, and set it's lat, long, and zoom level (12)
//NYC
var map = L.map('map').setView([40.754306, -73.985861], 12);
// big thanks to
// http://gis.stackexchange.com/questions/64406/getting-wfs-data-from-geoserver-into-leaflet
// for making this script a lot better
// Add MapBox Tiles
L.tileLayer('http://api.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoiY2hhcmxlc3JlaWQxIiwiYSI6ImpreUJGM3MifQ.w
    attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a>',
    maxZoom: 18
}).addTo(map);
var owsrootUrl = 'http://104.236.163.66:8080/geoserver/ows';
var defaultParameters = {
    service : 'WFS',
    version : '1.0',
    request : 'GetFeature',
    typeName : 'nyc_roads',
    maxFeatures : '200',
    outputFormat : 'text/javascript',
    format_options : 'callback:getJson',
    SrsName : 'EPSG:4326'
};
// get the srs name from Geoserver --> Layers
// that piece of information is critical to getting this working
var parameters = L.Util.extend(defaultParameters);
var URL = owsrootUrl + L.Util.getParamString(parameters);
//ajax to get map features
$.ajax({
    type: "POST",
    url: URL,
    dataType: 'jsonp',
    jsonpCallback : 'getJson',
    //upon success extraction of data
    success: function (data) {
        //console.log(data);
        //create a new geojson layer
        var geojson = new L.geoJson(data, {
                // apply a style
                style: {"color":"#ff7800","weight":2},
                //
                // and bind a popup showing the street name for each feature extracted.
                onEachFeature: function(feature, layer){
                    layer.bindPopup("street: " + feature.properties.name);
                    //console.log(feature.properties);
                }
        }).addTo(map);
    }
});
</source>
===Final Product===
The final page should look something like this:
[[Image:GeoserverEmbeddedMap.png|500px]]
[[Category:GIS]]

Latest revision as of 06:10, 8 February 2015

My Geodroplet adventure:

http://docs.geoserver.org/stable/en/user/gettingstarted/web-admin-quickstart/index.html

Logging In

Username/Password

Default username/pw are admin/geoserver. First thing I did was change those.

Server Status

Server status page shows some useful info:

GeoserverServerStatus.png

Data

On the left hand side menu, there is a cluster of items labeled "Data".

Here is what "Stores" looks like:

GeoserverStores.png

There's also "Layers," "Workspaces," etc. Not clear what all of this is for, I'm just browsing through it... Geoserver documentation isn't saying much about what these things are. (This is the web interface quick start, after all...)

Tutorial

Here is a tutorial: http://docs.geoserver.org/stable/en/user/gettingstarted/shapefile-quickstart/index.html

Importing Shape Data

Download the NYC roads shape file package linked to in the tutorial.

This goes in the Geoserver data directory. Remember from the Geodroplet page that this is a directory in our Tomcat webapp directory, so the whole thing is at /var/lib/tomcat7/webapps/geoserver/data/data (NOTE THE DOUBLE DATA!).

Move the map data to the Geoserver data directory:

sudo mv nyc_roads /var/lib/tomcat7/webapps/geoserver/data/data/.

You'll also have to change the owner to the Tomcat user:

sudo chown -R tomcat7:tomcat7 /var/lib/tomcat7/webapps/geoserver/data/data/nyc_roads/

Now we keep following the instructions.

Creating Workspace

Still logged into the Geoserver web portal as the admin, we go to Data and Workspaces, on the left hand side menu.

We pick add a new workspace, name it and populate it following the tutorial instructions [1].

Creating Store

Followed the tutorial instructions to create a store for NYC roads data...

Creating Layer

Created a layer for looking at that map... this is a lot of steps, making for a cumbersome workflow...

And finally, the document ends, at an anticlimactic moment. The map isn't that interesting, there are no other satellite or other map layers on it, and I'm not sure what to do with this.

[2]


An Embedded Map with Data from Geoserver

In order to test out the server's capabilities, I wanted to visualize the New York City streets dataset that I just imported in a site with an embedded map. For this purpose, I can use Leaflet, the Javascript maps app. I'll feed Leaflet a GeoJSON URL for the New York City street data, which Geoserver will serve up.

This will have three parts:

  • HTML (and CSS)
  • Javascript
  • URL for GeoJSON data

Before We Begin

The first thing we have to do, in order to access GeoJSON data via a URL, is fix the security settings of Geoserver. Right now, it is only set to serve up data to requests from "localhost." We will be accessing it from its IP address (and potentially other IP addresses, if it is a public server).

The error I was seeing was:

 XMLHttpRequest cannot load http://AAA.BBB.CCC.DDD:8080/geoserver/nyc_roads/ows?service=WFS&version=1.0.…&typeName=nyc_roads:nyc_roads&maxFeatures=50&outputFormat=application/json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://AAA.BBB.CCC.DDD' is therefore not allowed access.

Setting Up a Proxy Pass

Searching for this error yielded a stack overflow question that mentioned a Proxy Pass for Apache that needed to be set up [3]

The Geoserver tutorial states that to make requests from places other than "localhost", you have to set up an Apache proxy pass [4]

This involved editing the apache configuration file, at /etc/apache2/sites-available/000-default.conf on default Apache installations on Ubuntu systems, and added the following just before the VirtualHost *:80 tag:

ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /geoserver http://localhost:8080/geoserver
ProxyPassReverse /geoserver http://localhost:8080/geoserver

In plain English: when an outside server accesses the /geoserver directory, it is passed through a local proxy.

What a local proxy does is take requests from non-local servers to access the Geoserver, and makes them look like local requests.

Note that you'll have to do this, even if you're accessing Geoserver from the same IP address and the same machine, as long as you don't access Geoserver using an address like localhost:8080.

Enabling Apache Proxy Mod

I had to take one more step, before this worked, since my Apache installation didn't have the Proxy module enabled by default.

I ran this command to enable the Proxy mod:

sudo a2enmod proxy

after which, I restarted apache:

sudo service apache2 restart


Geoserver Use JSONP

Following this page [5] I enabled JSONP by editing /var/lib/tomcat7/webapps/geoserver/WEB-INF/web.xml as sudo, and adding this block:

  <context-param>
    <param-name>ENABLE_JSONP</param-name>
    <param-value>true</param-value>
  </context-param>

Now, when I make a request to my Geoserver in my Javascript code, it will specify the format as JSONP. My javascript code will look like this:

var owsrootUrl = 'http://AA.BB.CC.DD:8080/geoserver/ows';

var defaultParameters = {
    service : 'WFS',
    version : '1.0',
    request : 'GetFeature',
    typeName : 'nyc_roads:nyc_roads',
    maxFeatures : '100',
    outputFormat : 'text/javascript',
    format_options : 'callback:getJson',
};

var parameters = L.Util.extend(defaultParameters);
var URL = owsrootUrl + L.Util.getParamString(parameters);

and when we use some ajax for the map features, it will look like:

$.ajax({
    type: "POST",
    url: URL,
    dataType: 'jsonp',
    jsonpCallback : 'getJson',

Embedded Map Example Page

The following files can be served up by a web server to serve up a map with Leaflet.

Right now, the embedded objects from Geoserver are not showing up, but when I print them in the browser's console they all seem to be intact.

HTML: index.html

<html>
<head>
    <title>Geodrop demo</title>

    <!-- load the leaflet library -->
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
    <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>


     <!-- load my style sheet -->
    <link rel="stylesheet" type="text/css" href="style.css">


    <!-- load jquery -->
    <script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
    <script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>

</head>
<body>

    <!-- create a map div -->
    <div id="map"></div>

</body>

     <script type="text/javascript" src="mymap.js"></script>

</html>

CSS: style.css

#map {
    height: 600px;
    width: 600px;
}

Javascript: mymap.js

// create the map, assign to the mao div, and set it's lat, long, and zoom level (12)
//NYC
var map = L.map('map').setView([40.754306, -73.985861], 12);

// big thanks to
// http://gis.stackexchange.com/questions/64406/getting-wfs-data-from-geoserver-into-leaflet
// for making this script a lot better

// Add MapBox Tiles
L.tileLayer('http://api.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoiY2hhcmxlc3JlaWQxIiwiYSI6ImpreUJGM3MifQ.w
    attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a>',
    maxZoom: 18
}).addTo(map);

var owsrootUrl = 'http://104.236.163.66:8080/geoserver/ows';

var defaultParameters = {
    service : 'WFS',
    version : '1.0',
    request : 'GetFeature',
    typeName : 'nyc_roads',
    maxFeatures : '200',
    outputFormat : 'text/javascript',
    format_options : 'callback:getJson',
    SrsName : 'EPSG:4326'
};
// get the srs name from Geoserver --> Layers
// that piece of information is critical to getting this working

var parameters = L.Util.extend(defaultParameters);
var URL = owsrootUrl + L.Util.getParamString(parameters);

//ajax to get map features
$.ajax({
    type: "POST",
    url: URL,
    dataType: 'jsonp',
    jsonpCallback : 'getJson',

    //upon success extraction of data
    success: function (data) {

        //console.log(data);

        //create a new geojson layer
        var geojson = new L.geoJson(data, {

                // apply a style
                style: {"color":"#ff7800","weight":2},
                //
                // and bind a popup showing the street name for each feature extracted.
                onEachFeature: function(feature, layer){
                    layer.bindPopup("street: " + feature.properties.name);
                    //console.log(feature.properties);
                }
        }).addTo(map);
    }
});

Final Product

The final page should look something like this:

GeoserverEmbeddedMap.png