initial commit

This commit is contained in:
s.meijer
2012-12-24 02:19:55 +01:00
commit dac77d5a7e
11 changed files with 583 additions and 0 deletions

22
.gitattributes vendored Normal file
View File

@@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

163
.gitignore vendored Normal file
View File

@@ -0,0 +1,163 @@
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.vspscc
.builds
*.dotCover
## TODO: If you have NuGet Package Restore enabled, uncomment this
#packages/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
# Visual Studio profiler
*.psess
*.vsp
# ReSharper is a .NET coding add-in
_ReSharper*
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish
# Others
[Bb]in
[Oo]bj
sql
TestResults
*.Cache
ClientBin
stylecop.*
~$*
*.dbmdl
Generated_Code #added for RIA/Silverlight projects
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
############
## Windows
############
# Windows image file caches
Thumbs.db
# Folder config file
Desktop.ini
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
# Mac crap
.DS_Store

36
example/esri.html Normal file
View File

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet.GeoSearch / Esri Provider</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.ie.css" /><![endif]-->
<script src="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.js"></script>
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="../src/js/l.control.geosearch.js"></script>
<script src="../src/js/l.geosearch.provider.esri.js"></script>
<link rel="stylesheet" href="../src/css/l.geosearch.css" />
</head>
<body>
<div id="map" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></div>
<script type="text/javascript">
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png';
var basemap = new L.TileLayer(cloudmadeUrl, {maxZoom: 18});
var map = new L.Map('map', {
layers: [basemap],
center: new L.LatLng(53.2, 5.8), zoom: 12
});
new L.Control.GeoSearch({
provider: new L.GeoSearch.Provider.Esri()
}).addTo(map);
</script>
</body>
</html>

37
example/google.html Normal file
View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet.GeoSearch / Google Provider</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.ie.css" /><![endif]-->
<link rel="stylesheet" href="leaflet.label.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.js"></script>
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="../src/js/l.control.geosearch.js"></script>
<script src="../src/js/l.geosearch.provider.google.js"></script>
<link rel="stylesheet" href="../src/css/l.geosearch.css" />
</head>
<body>
<div id="map" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></div>
<script type="text/javascript">
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png';
var basemap = new L.TileLayer(cloudmadeUrl, {maxZoom: 18});
var map = new L.Map('map', {
layers: [basemap],
center: new L.LatLng(53.2, 5.8), zoom: 12
});
new L.Control.GeoSearch({
provider: new L.GeoSearch.Provider.Google()
}).addTo(map);
</script>
</body>
</html>

View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet.GeoSearch / OSM Provider</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.ie.css" /><![endif]-->
<link rel="stylesheet" href="leaflet.label.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.js"></script>
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="../src/js/l.control.geosearch.js"></script>
<script src="../src/js/l.geosearch.provider.openstreetmap.js"></script>
<link rel="stylesheet" href="../src/css/l.geosearch.css" />
</head>
<body>
<div id="map" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></div>
<script type="text/javascript">
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png';
var basemap = new L.TileLayer(cloudmadeUrl, {maxZoom: 18});
var map = new L.Map('map', {
layers: [basemap],
center: new L.LatLng(53.2, 5.8), zoom: 12
});
new L.Control.GeoSearch({
provider: new L.GeoSearch.Provider.OpenStreetMap()
}).addTo(map);
</script>
</body>
</html>

43
readme.md Normal file
View File

@@ -0,0 +1,43 @@
#Leaflet.GeoSearch
Adds support for address lookup (a.k.a. geocoding / geoseaching) to Leaflet.
Check out the [demo](http://smeijer.github.com/GeoSearch/)
#About the control
The control uses so called providers to take care of building the correct service url and parsing the retrieved data into an uniformal format. Thanks to this split-up, it is pretty easy to write your own providers, so you can use your own geocoding service(s).
The control comes with an default set of three providers:
- L.GeoSearch.Provider.Esri
- L.GeoSearch.Provider.Google
- L.GeoSearch.Provider.OpenStreetMap
Using these are pretty simple.
#Using the control
For example, to use the Esri provider:
````
new L.Control.GeoSearch({
provider: new L.GeoSearch.Provider.Esri()
}).addTo(map);
````
Or if you prefer using Google
````
new L.Control.GeoSearch({
provider: new L.GeoSearch.Provider.Google()
}).addTo(map);
````
Some people are really loving open source and by that openstreetmap
````
new L.Control.GeoSearch({
provider: new L.GeoSearch.Provider.OpenStreetMap()
}).addTo(map);
````
I really can't make it any harder. Checkout the providers to see how easy it is to write your own.

38
src/css/l.geosearch.css Normal file
View File

@@ -0,0 +1,38 @@
.leaflet-center {
width: 40%;
margin-left: auto;
margin-right: auto;
position: relative;
}
.leaflet-control-geosearch, .leaflet-control-geosearch ul {
border-radius: 7px;
background: none repeat scroll 0 0 rgba(0, 0, 0, 0.25);
margin: 10px 0 0 0;
padding: 5px;
width: 100%;
height: auto;
}
.leaflet-control-geosearch-msg ul {
list-style: none;
display: none;
height: auto;
background: none;
padding: 0;
}
.leaflet-control-geosearch ul li {
background: none repeat scroll 0 0 rgba(255, 255, 255, 0.75);
border-radius: 4px;
margin: 2px 0;
padding: 4px;
font: 12px arial;
text-indent: 4px;
}
.leaflet-container .leaflet-control-geosearch input {
width: 100%;
height: 28px;
padding: 0;
text-indent: 8px;
background: rgba(255, 255, 255, 0.75);
border-radius: 4px;
border: none;
}

View File

@@ -0,0 +1,126 @@
/*
* L.Control.GeoSearch - search for an address and zoom to it's location
* https://github.com/smeijer/leaflet.control.geosearch
*/
L.GeoSearch = {};
L.GeoSearch.Provider = {};
L.GeoSearch.Result = function (x, y, label) {
this.X = x;
this.Y = y;
this.Label = label;
};
L.Control.GeoSearch = L.Control.extend({
options: {
position: 'topcenter'
},
initialize: function (options) {
this._config = {};
this.setConfig(options);
},
setConfig: function (options) {
this._config = {
'country': options.country || '',
'provider': options.provider,
'searchLabel': options.searchLabel || 'search for address...',
'notFoundMessage' : options.notFoundMessage || 'Sorry, that address could not be found.',
'messageHideDelay': options.messageHideDelay || 3000,
'zoomLevel': options.zoomLevel || 18,
};
},
onAdd: function (map) {
var $controlContainer = $(map._controlContainer);
if ($controlContainer.children('.leaflet-top.leaflet-center').length == 0) {
$controlContainer.append('<div class="leaflet-top leaflet-center"></div>');
map._controlCorners.topcenter = $controlContainer.children('.leaflet-top.leaflet-center').first()[0];
}
this._map = map;
this._container = L.DomUtil.create('div', 'leaflet-control-geosearch');
var searchbox = document.createElement('input');
searchbox.id = 'leaflet-control-geosearch-qry';
searchbox.type = 'text';
searchbox.placeholder = this._config.searchLabel;
this._searchbox = searchbox;
var msgbox = document.createElement('div');
msgbox.id = 'leaflet-control-geosearch-msg';
msgbox.className = 'leaflet-control-geosearch-msg';
this._msgbox = msgbox;
var resultslist = document.createElement('ul');
resultslist.id = 'leaflet-control-geosearch-results';
this._resultslist = resultslist;
$(this._msgbox).append(this._resultslist);
$(this._container).append(this._searchbox, this._msgbox);
L.DomEvent
.addListener(this._container, 'click', L.DomEvent.stop)
.addListener(this._container, 'keypress', this._onKeyUp, this);
L.DomEvent.disableClickPropagation(this._container);
return this._container;
},
geosearch: function (qry) {
try {
var provider = this._config.provider;
var url = provider.GetServiceUrl(qry);
$.getJSON(url, function (data) {
try {
var results = provider.ParseJSON(data);
if (results.length == 0)
throw this._config.notFoundMessage;
this._showLocation(results[0].X, results[0].Y);
}
catch (error) {
this._printError(error);
}
}.bind(this));
}
catch (error) {
this._printError(error);
}
},
_showLocation: function (x, y) {
if (typeof this._positionMarker === 'undefined')
this._positionMarker = L.marker([y, x]).addTo(this._map);
else
this._positionMarker.setLatLng([y, x]);
this._map.setView([y, x], this._config.zoomLevel, false);
},
_printError: function(message) {
$(this._resultslist)
.html('<li>'+message+'</li>')
.fadeIn('slow').delay(this._config.messageHideDelay).fadeOut('slow',
function () { $(this).html(''); });
},
_onKeyUp: function (e) {
var escapeKey = 27;
var enterKey = 13;
if (e.keyCode === escapeKey) {
$('#leaflet-control-geosearch-qry').val('');
$(this._map._container).focus();
}
else if (e.keyCode === enterKey) {
this.geosearch($('#leaflet-control-geosearch-qry').val());
}
}
});

View File

@@ -0,0 +1,27 @@
/**
* L.Control.GeoSearch - search for an address and zoom to it's location
* L.GeoSearch.Provider.Esri uses arcgis geocoding service
* https://github.com/smeijer/leaflet.control.geosearch
*/
L.GeoSearch.Provider.Esri = function (options) {
this._config = options || {};
var self = this;
this.GetServiceUrl = function (qry) {
var country = self._config.country || '';
return 'http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find?text=' + qry + '&sourceCountry=' + country + '&f=json';
};
this.ParseJSON = function (data) {
if (data.locations.length == 0)
return [];
var results = [];
for (var i = 0; i < data.locations.length; i++)
results.push(new L.GeoSearch.Result(data.locations[i].feature.geometry.x, data.locations[i].feature.geometry.y, data.locations[i].name));
return results;
};
};

View File

@@ -0,0 +1,27 @@
/**
* L.Control.GeoSearch - search for an address and zoom to it's location
* L.GeoSearch.Provider.Google uses google geocoding service
* https://github.com/smeijer/leaflet.control.geosearch
*/
L.GeoSearch.Provider.Google = function (options) {
this._config = options || {};
var self = this;
this.GetServiceUrl = function (qry) {
var sensor = self._config.sensor || false;
return 'http://maps.googleapis.com/maps/api/geocode/json?address='+qry+'&sensor='+ sensor;
};
this.ParseJSON = function (data) {
if (data.results.length == 0)
return [];
var results = [];
for (var i = 0; i < data.results.length; i++)
results.push(new L.GeoSearch.Result(data.results[i].geometry.location.lng, data.results[i].geometry.location.lat, data.results[i].formatted_address));
return results;
};
};

View File

@@ -0,0 +1,27 @@
/**
* L.Control.GeoSearch - search for an address and zoom to it's location
* L.GeoSearch.Provider.OpenStreetMap uses openstreetmap geocoding service
* https://github.com/smeijer/leaflet.control.geosearch
*/
L.GeoSearch.Provider.OpenStreetMap = function (options) {
this._config = options || {};
var self = this;
this.GetServiceUrl = function (qry) {
var countryCode = self._config.countryCode || '';
return 'http://nominatim.openstreetmap.org/search/?q=' + qry + '&format=json&countrycodes='+countryCode;
};
this.ParseJSON = function (data) {
if (data.length == 0)
return [];
var results = [];
for (var i = 0; i < data.length; i++)
results.push(new L.GeoSearch.Result(data[i].lon, data[i].lat, data[i].display_name));
return results;
};
};