I'd like to upload shapefiles using GeoServer REST API and C#. So far, I can create workspaces using the REST API and C#. From GeoServer documentation (specific to cURL), the difference between creating a workspace and uploading a shapefile is in the HTTP Method (workspace creation uses POST
, shapefile uploading uses PUT
), ContentType (workspace creation uses application/xml
, shapefile uploading uses application/zip
), and finally there is the --data-binary
parameter in shapefile uploading.
The code I use for creating workspace is shown below. Can anyone kindly help me refactor this code so that I can use it to upload a shapefile.
String gUrl = "http://localhost:8081/geoserver/rest/workspaces";
WebRequest request = WebRequest.Create(gUrl);
request.ContentType = "text/xml";
request.Method = "POST";
request.Credentials = new NetworkCredential("geoServer-username", "password");
byte[] buffer = Encoding.GetEncoding("UTF-8").GetBytes("<workspace><name>new_workspace_csharp_2</name></workspace>");
Stream requestStream = request.GetRequestStream();
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Close();
WebResponse response = request.GetResponse();
Console.Write("Response from GeoServer: " + response);
EDITED:
I've managed to make some headway, and I can now upload a shapefile using C# and the GeoServer REST API. My refactoring effort, which now works, is shown below:
public bool UploadShapeFile(string workspace, string dsName, Uri zipUri)
{
String fileUri = zipUri.AbsolutePath;
Console.Write(fileUri);
byte[] localShapeFile = readLocalShapeFile(fileUri);
String sUrl = "http://localhost:8081/geoserver/rest/workspaces/cs_ws1/datastores/cs_ds1/file.shp";
WebRequest request = WebRequest.Create(sUrl);
request.ContentType = "application/zip";
request.Method = "PUT";
request.Credentials = new NetworkCredential("gs-username", "password");
// byte[] buffer = Encoding.GetEncoding("UTF-8").GetBytes(@fileUri);
Stream requestStream = request.GetRequestStream();
requestStream.Write(localShapeFile, 0, localShapeFile.Length);
requestStream.Close();
WebResponse response = request.GetResponse();
Console.Write("Response from GeoServer: " + response);
return false;
}
private byte[] readLocalShapeFile(string filePath)
{
byte[] buffer;
FileStream fStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
try {
int length = (int)fStream.Length;
buffer = new byte[length];
int count;
int sum = 0;
// Read until Read method returns 0 - End of stream reached
while ((count = fStream.Read(buffer, sum, length - sum)) > 0)
sum += count;
}
finally {
fStream.Close();
}
return buffer;
}
However, I still believe there can be a more elegant way of doing this. Any suggestions will be highly appreciated.
Best Answer
I've been able to achieve this using the code segments below. But it'll be great if someone can come up with a better solution.
Part I: Uploading a shape file to GeoServer without PostGIS
Part II: Upload Shape File to GeoServer's PostGIS store First, create a DB Data Store as shown:
Then, create a DB Table and FeatureType as shown:
Finally, upload the shape file using the
UploadShapeFile(..)
method above, specifying the previously created (postgis) data store as thedsName
.