Monday, November 13, 2017

Geoserver WFS-T PostGIS (PostgreSQL) Layer Read-Only

An unexpected Read-Only message is common when attempting a Geoserver WFS-T request via the Demo page.  This is also true of WFS-T on a PostGIS-backed Layer.

Here are a list of possible culprits:

  1. Verify the layer is writable by the Postgres role (user account) which you've used to authenticate in Geoserver, via the Store dialog for that Layer.
  2. The table must have a primary key in Postgres.  It may be necessary to "Reload Feature Type" under the Layer page > Data Tab > Feature Type Details section.  It also be necessary to "Expose Primary Keys" in the Store for the Layer.
  3. The WFS-T Demos will not successfully authenticate out-of-the-box (which will probably give a different error message).  See my post on the issue, and how to resolve it.
  4. If you are using my work around, linked from above, you are using anonymous authentication (for testing only, of course!).  You will need to create a write rule that applies to the anonymous role and the workspace which relates to your Layer/Store.

In my latest experience with this error, culprit #4 got me :-p

Thursday, October 19, 2017

Solution, Geoserver bug with authenticated requests

Geoserver ships with a good list of helpful Demo requests -- however, the authenticated requests fail if you do not add the relevant URL path to a Filter Chain which includes a "form" authentication filter.

If you run any Demo request involving authentication without the relevant Filter Chain modification you will see the following message:

HTTP response: 401 No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken

The same response is seen when running the request with curl, e.g.:

curl -u admin:geoserver "http://localhost:8080/geoserver/wfs?request=GetFeature&version=1.1.0&typeName=topp:states&outputFormat=GML2&FEATUREID=states.3"

You can resolve this issue by adding the relevant URL path suffix (e.g., /wcs*  or /wfs*) to the "web" Filter Chain, which includes the "form" Authentication Filter.

Access this dialog in the Web Administration interface under Security > Authentication > Filter Chains > web.



I've commented on the bug in the Geoserver project JIRA -- to resolve this bug this issue should be either noted or the underlying xml's changed -- otherwise the Demos fail.




Wednesday, June 28, 2017

Georeference a non-referenced image with gdal_translate

This technique is useful for georeferencing an image that you could be getting from a WMS server.

To get an image from a WMS Server, first do a capabilities request via the URL.  This will return an XML with parameters.  The result will look something like this (you could also substitute your target WMS, layer, bbox, etc.

http://imagery.pasda.psu.edu/arcgis/services/pasda/PAMAP_cycle2/MapServer/WMSServer?service=WMS&version=1.1.0&request=GetMap&layers=11&styles=&bbox=-77.16641161363148171,39.76300177722033169,%20-77.16220203861050209,39.76481826348722137&width=800&height=400&srs=EPSG:4326&format=image/jpeg

change the format parameter to image/tiff to download

if gdal isn't already installed, do so now, and navigate to the gdal bin directory, if it isn't on your path

gdal translate will require input file, output file, the desired spatial reference system, and ground control points (gcp) which you will calculate from the bounding box you entered above and the image pixel size (800 by 400).  These correspond to the corners of the image (coordinates differ from above slightly, not intended).

gdal_translate c:\temp\WMSServer.tiff c:\temp\aerial.tif -of GTiff -a_srs EPSG:4326 -gcp 0 0 -77.16694 39.764799 -gcp 800 400 -77.161927 39.763017 -gcp 0 400 -77.16694 39.763017 -gcp 800 0 -77.161927 39.764799

Use gdal_warp for further transformation, if a simple scaling wasn't adequate.  This is particularly necessary for Geoserver.  In that case, also use the -co tfw=yes parameter to create a world file, since Geoserver doesn't recognize srs in the standalone GTiff.

It looks like this: gdalwarp c:\temp\aerial.tif c:\temp\aerialw.tif -of GTiff -co tfw=yes -t_srs EPSG:4326

Tuesday, October 20, 2015

Local Vagrant VM as part of a deployment strategy

Local Vagrant VM as part of a deployment strategy

Previously I discuss setting up a Vagrant EC2 VM for web application deployment. In this post, I will walk through the process of setting up a local development VM with the objective of maintaining a commmon environment between the local and remote (EC2) VM’s.

The local VM

I assume that you’ve already installed Virtual Box guest additions

(1) Create the directory for the new Vagrant configuration files – I will call mine vagrant-local mkdir vagrant-local – and move to that directory cd vagrant-local.

(2) Create a new vagrantfile, using your favorite text editor (e.g., vi vagrantfile) and insert the following text

Vagrant.configure(2) do |config|
  config.vm.box = "hashicorp/precise64"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.synced_folder "..\\vagrant_data", "/vagrant_data"
  config.vm.provider "virtualbox" do |vb|
  #   # Display the VirtualBox GUI when booting the machine
    vb.gui = false
  #
  #   # Customize the amount of memory on the VM:
  #   vb.memory = "1024"
  end
  # config.vm.provision :shell, path: "bootstrap.sh"
end

(3) Save this file, and bring the vagrant VM vagrant up

(4) As you install packages, make sure to add those lines to a new file, (vi bootstrap.sh). You can also add checks where necessary. My bootstrap.sh is long, but here’s a portion of it for example:

#!/usr/bin/env bash

# install and configure linux tools
sudo apt-get -y update
# sudo apt-get -y upgrade
sudo apt-get -y install unattended-upgrades make vim acl
sudo addgroup web
sudo adduser www-data web
sudo usermod -a -G web vagrant

# apache install and config
sudo apt-get install -y apache2
if ! [ -L /var/www ]; then
  rm -rf /var/www
  ln -fs /vagrant_data /var/www
fi
sudo chown www-data:web /var/www
sudo a2enmod rewrite
sudo /etc/init.d/apache2 restart

# sqlite install and config
sudo apt-get -y install sqlite3 libspatialite3 spatialite-bin

(5) Uncoment line second to end (config.vm.provision :shell, path: "bootstrap.sh") in your vagrantfile with your favorite text editor (e.g., vi vagrantfile) to configure provisioning via bootstrap.sh on a new VM when vagrant up is run.

You will need to make the same changes to ..\vagrant-aws\vagrantfile and a ..\vagrant-aws\bootstrap.sh, created in the previous post, to syncronize your development and deployment provisioning

(6) Destroy the existing vagrant instance, including all files created when you brought it up vagrant destroy and bring up the new instance vagrant up

Written with StackEdit.

Friday, October 16, 2015

Vagrant on AWS with Windows

Vagrant on AWS with Windows

Required installations:
– AWS CLI
– VirtualBox
– Vagrant
– an existing EC2 instance with an account private key on your local file system.

[Optional] If you use PuTTy ssh client, you may want to install and configure the Vagrant PuTTY plugin, by following instructions here: https://github.com/nickryand/vagrant-multi-putty. You will also need to make a symbolic link to the executable, using the following command.

> mklink D:\Vagrant\embedded\bin\putty.exe "C:\Program Files (x86)\PuTTY\putty.exe"

(1) Use the AWS CLI/Security Token Service to generate temporary credentials for AWS

> aws sts get-session-token  

The credentials returned by this command will be valid for 1 hour.

(2) Install the Vagrant AWS plugin.

> vagrant plugin install vagrant-aws

(3) Add the “dummy” Box provided by the vagrant-aws project. This is a barebones Box compatible with AWS. We will flesh this out in the Vagrantfile to be created in the next step.

> vagrant box add dummy https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box

(4) Create a new directory to hold files for this Vagrant instance. I’m calling this vagrant-aws.

> mkdir vagrant-aws

(5) With your favorite text editor create a file called Vagrantfile inside this new directory. Edit this file vagrant-aws\Vagrantfile copying and pasting the following to the file (source).

Vagrant.configure("2") do |config|
  config.vm.box = "dummy"

  config.vm.provider :aws do |aws, override|
    aws.access_key_id = "YOUR KEY"
    aws.secret_access_key = "YOUR SECRET KEY"
    aws.session_token = "SESSION TOKEN"
    aws.keypair_name = "KEYPAIR NAME"

    aws.ami = "ami-7747d01e"

    override.ssh.username = "ubuntu"
    override.ssh.private_key_path = "PATH TO YOUR PRIVATE KEY"
  end
end

(6) Now edit this text with the credentials returned by AWS STS (from above). You can use a different AMI (the current one given is for Ubuntu 12.04 x64) or change many other options, as described in the Vagrant AWS plugin documentation.

(7) Now you can bring the instance up with Vagrant, first making sure you are in the directory where you had created the Vagrantfile.

> cd vagrant-aws
> vagrant up

To work on your new Vagrant VM, use vagrant ssh or vagrant putty if you set up Putty using the plugin mentioned below. Once you’re finished, you can use vagrant destroy to completely blow away this instance, or some other vagrant command if you need to come back to the instance.

Next: The local VM

Friday, September 25, 2015

I'm back!

I'm back from my cross country bike ride!  On a completely different topic, my book with Packt Publishing, is finished and available for pre-order on Amazon, Barnes and Noble, and other fine book retailers:


Thursday, August 6, 2015

Out to ride -- back sometime in September

I'm on a cross country bike ride!

My progress as of 8/4/15:


Photos