Skip to content

Commit

Permalink
added picking sample
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverheilig committed Jan 17, 2016
1 parent b590ebe commit 04463c3
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 7 deletions.
9 changes: 2 additions & 7 deletions 07-ThematicTilesHandler.ashx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,11 @@ public void ProcessRequest(HttpContext context)
var queryWindow = TransformTools.TileToWgs(x, y, z);

// build the sql
string sx1 = Convert.ToString(queryWindow.Left, CultureInfo.InvariantCulture);
string sy1 = Convert.ToString(queryWindow.Top, CultureInfo.InvariantCulture);
string sx2 = Convert.ToString(queryWindow.Right, CultureInfo.InvariantCulture);
string sy2 = Convert.ToString(queryWindow.Bottom, CultureInfo.InvariantCulture);

var strSql = string.Format(
var strSql = string.Format(CultureInfo.InvariantCulture,
@"SELECT WorldGeom.Id, AsBinary(Geometry), Pop/Area as PopDens FROM WorldGeom " +
@"JOIN WorldData on WorldData.Id = WorldGeom.Id " +
@"WHERE MBRIntersects(Geometry, BuildMbr({0}, {1}, {2}, {3}));",
sx1, sy2, sx2, sy1);
queryWindow.Left, queryWindow.Top, queryWindow.Right, queryWindow.Bottom);

var choropleth = new Classification<double, Color>
{
Expand Down
186 changes: 186 additions & 0 deletions 08-SpatialPicking.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">

<html>
<head>
<title>Leaflet NonTiledLayer Example</title>
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
<link href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" rel="stylesheet">
<style>
body {
padding: 0;
margin: 0;
}

html,
body,
#map {
height: 100%;
}

.info {
padding: 6px 8px;
font: 14px/16px Arial, Helvetica, sans-serif;
background: white;
background: rgba(255,255,255,0.8);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
}

.info h4 {
margin: 0 0 5px;
color: #777;
}

.legend {
text-align: left;
line-height: 18px;
color: #555;
}

.legend i {
width: 18px;
height: 18px;
float: left;
margin-right: 8px;
opacity: 0.7;
}
</style>
</head>

<body>
<div id="map" />
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script src="./NonTiledLayer.js"></script>
<script src="./NonTiledLayer.WMS.js"></script>
<script src="./token.js"></script>
<script>
// initialize leaflet
var map = new L.Map('map');

// center Karlsruhe
map.setView(new L.LatLng(50, 10), 4);

// using the xmap WMS servlet
var xMapUrl = 'https://xmap-eu-n-test.cloud.ptvgroup.com';
var xMapAttribution = '<a href="http://www.ptvgroup.com">PTV<\/a>, HERE';

// add the xServer layers
// set the layer groups for default and sandbox
var baseLayers = {
"PTV classic": getLayers(xMapUrl + '/WMS/WMS', "", xMapAttribution),
"PTV sandbox": getLayers(xMapUrl + '/WMS/WMS', "sandbox", xMapAttribution).addTo(map),
"PTV silkysand": getLayers(xMapUrl + '/WMS/WMS', "silkysand", xMapAttribution)
};

L.control.layers(baseLayers, null).addTo(map);

// add dymamic tile layer
var myTileLayerUrl = '07-ThematicTilesHandler.ashx?x={x}&y={y}&z={z}',
myTileLayer = new L.TileLayer(myTileLayerUrl, {
maxZoom: 20, zIndex: 100
});
map.addLayer(myTileLayer);

// add click handler
map.on('click', onMapClick);

function onMapClick(e) {
$.ajax({
url: "08-SpatialPickingHandler.ashx?lat=" + e.latlng.lat + "&lng=" + e.latlng.lng,
type: "GET",
success: function (data, status, xhr) {
displayResult(data, e.latlng);
}
});
}

var pickedFeature;
var popup = L.popup();

function displayResult(pickedPolygon, latlng) {
if (pickedFeature)
map.removeLayer(pickedFeature);
var feature = {
"type": "Feature",
"properties": {
"style": {
weight: 4, color: "#222", opacity: 1,
fillColor: "#fff", fillOpacity: 0.5
}
}
};

feature.geometry = pickedPolygon.geometry;

pickedFeature = L.geoJson([feature], {
style: function (feature) {
return feature.properties && feature.properties.style;
}
}).addTo(map);

popup.setLatLng(latlng)
.setContent('<h4>'+pickedPolygon.properties.name + '</h4><b>Area: </b>' +
new Intl.NumberFormat().format(pickedPolygon.properties.area) + ' km2<br><b>Population: </b>' + new Intl.NumberFormat().format(pickedPolygon.properties.pop))
.openOn(map);
};

// using legend code from http://leafletjs.com/examples/choropleth-example.html
var legend = L.control({ position: 'bottomright' });

legend.onAdd = function (map) {

var div = L.DomUtil.create('div', 'info legend'),
grades = [0, 50, 100, 250, 500, 1000, 2500],
labels = [];
div.innerHTML = '<h4>Population density</h4>';

// loop through our density intervals and generate a label with a colored square for each interval
for (var i = 0; i < grades.length; i++) {
div.innerHTML +=
'<i style="background:' + getColor(grades[i] + 1) + '"></i> ' +
grades[i] + (grades[i + 1] ? '&ndash;' + grades[i + 1] + '<br>' : '+');
}

return div;
};

legend.addTo(map);

// get color depending on population density value
function getColor(d) {
return d > 2500 ? '#800080' :
d > 1000 ? '#8B0000' :
d > 500 ? '#FF0000' :
d > 250 ? '#FFA500' :
d > 100 ? '#FFFF00' :
d > 50 ? '#90EE90' :
'#008000';
}

// returns a layer group for xmap back- and foreground layers
function getLayers(url, style, attribution) {
var background = new L.TileLayer.WMS(url, {
maxZoom: 19,
minZoom: 0,
noWrap: true,
layers: style ? 'xmap-' + style + '-bg' : 'xmap-ajaxbg',
format: 'image/gif',
transparent: false,
attribution: attribution
});

var foreground = new L.NonTiledLayer.WMS(url + '?xtok=' + token, {
layers: style ? 'xmap-' + style + '-fg' : 'xmap-ajafbg',
format: 'image/gif',
transparent: true,
attribution: attribution
});

return L.layerGroup([background, foreground]);
}

</script>
</body>
</html>
Expand Down
1 change: 1 addition & 0 deletions 08-SpatialPickingHandler.ashx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%@ WebHandler Language="C#" CodeBehind="08-SpatialPickingHandler.ashx.cs" Class="SpatialTutorial.SpatialPickingHandler" %>
111 changes: 111 additions & 0 deletions 08-SpatialPickingHandler.ashx.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Globalization;
using System.Configuration;
using System.Data.SQLite;

namespace SpatialTutorial
{
/// <summary>
/// Summary description for SpatialPickHandler
/// </summary>
public class SpatialPickingHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
try
{
//Parse request parameters
double lat, lng;
if (!double.TryParse(context.Request.Params["lat"], NumberStyles.Float, CultureInfo.InvariantCulture, out lat))
throw (new ArgumentException("Invalid parameter"));
if (!double.TryParse(context.Request.Params["lng"], NumberStyles.Float, CultureInfo.InvariantCulture, out lng))
throw (new ArgumentException("Invalid parameter"));

// convert line string to polygon
var text = "";// isoResult.wrappedIsochrones[0].polys.wkt;
text = text.Replace("LINESTRING (", "POLYGON ((");
text = text.Replace(")", "))");


var strSql = string.Format(CultureInfo.InvariantCulture,
@"SELECT WorldGeom.Id, AsText(Geometry), Name, Region, Area, Pop FROM WorldGeom " +
@"JOIN WorldData on WorldData.Id = WorldGeom.Id " +
@"WHERE Intersects(Geometry, MakePoint({0}, {1}));",
lng, lat);

using (SQLiteCommand command = new SQLiteCommand(strSql, Global.cn))
using (SQLiteDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
string type;

int id = reader.GetInt32(0);
string str = reader.GetString(1);
string name = reader.GetString(2);
string region = reader.GetString(3);
double area = reader.GetDouble(4);
double pop = reader.GetDouble(5);

// convert wkt to GeoJson
if (str.StartsWith("POLYGON"))
{
type = "Polygon";
str = str
.Replace("POLYGON", "")
.Trim();
}
else
{
type = "MultiPolygon";
str = str
.Replace("MULTIPOLYGON", "")
.Trim();
}

str = str
.Replace(", ", "],[")
.Replace(" ", ",")
.Replace("(", "[")
.Replace(")", "]")
.Replace(",", ", ");

// buiold response
context.Response.ContentType = "text/json";
context.Response.Write(string.Format(CultureInfo.InvariantCulture,
@"{{""geometry"": {{""type"": ""{0}"",""coordinates"": [{1}]}},""type"": ""Feature""," +
@"""properties"": {{""name"": ""{2}"", ""region"": ""{3}"",""area"": ""{4}"",""pop"": ""{5}""}}}}",
type, str, name, region, area, pop));

//{
// ""type"": """ + type + @""",
// ""description"": """ + string.Format(CultureInfo.InvariantCulture, "{0:0,0}", name) + " households<br>"
// + string.Format(CultureInfo.InvariantCulture, "{0:n}", 0) + " avg. power" + @""",
// ""coordinates"": [" + str + @"]
//}");
return;
}
}

// no result - return empty json
context.Response.ContentType = "text/json";
context.Response.Write("{}");
}
catch (Exception ex)
{
// no result - return empty json
context.Response.ContentType = "text/json";
context.Response.Write(@"{ ""error"": """ + ex.Message + @"""}");
}
}

public bool IsReusable
{
get { return true; }
}
}
}
1 change: 1 addition & 0 deletions Global.asax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ protected void Application_Start(object sender, EventArgs e)
SQLiteCommand cm = new SQLiteCommand(String.Format("SELECT load_extension('{0}');", "libspatialite-4.dll"), cn);
cm.ExecuteNonQuery();
}

protected void Session_Start(object sender, EventArgs e)
{

Expand Down
6 changes: 6 additions & 0 deletions SpatialTutorial.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
Expand Down Expand Up @@ -75,6 +76,7 @@
<Content Include="02-DynamicTileProvider.html" />
<Content Include="06-SpatialLiteTiles.html" />
<Content Include="07-ThematicTiles.html" />
<Content Include="08-SpatialPicking.html" />
<Content Include="Global.asax" />
<Content Include="index.html" />
<Content Include="token.js" />
Expand Down Expand Up @@ -107,6 +109,9 @@
<Compile Include="07-ThematicTilesHandler.ashx.cs">
<DependentUpon>07-ThematicTilesHandler.ashx</DependentUpon>
</Compile>
<Compile Include="08-SpatialPickingHandler.ashx.cs">
<DependentUpon>08-SpatialPickingHandler.ashx</DependentUpon>
</Compile>
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
Expand All @@ -129,6 +134,7 @@
<ItemGroup />
<ItemGroup>
<Content Include="02-DynamicTilesHandler.ashx" />
<Content Include="08-SpatialPickingHandler.ashx" />
<None Include="App_Data\db.sqlite" />
<Content Include="07-ThematicTilesHandler.ashx" />
</ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<li><a href="05-SymbolScaling.html">Step 5: Scale the objects</a></li>
<li><a href="06-SpatialLiteTiles.html">Step 6: Fill the tiles with our data</a></li>
<li><a href="07-ThematicTiles.html">Step 7: Join with business data and create thematic maps</a></li>
<li><a href="08-SpatialPicking.html">Step 8: Pick elements on the map</a></li>
</ul>
</body>
</html>

0 comments on commit 04463c3

Please sign in to comment.