improve projections support, add EPSG:3395 (real mercator)

This commit is contained in:
Mourner 2011-05-31 12:36:05 +03:00
parent ed168a30b2
commit e7410e6e03
15 changed files with 106 additions and 98 deletions

View File

@ -4,7 +4,7 @@ Leaflet Changelog
## 0.2 (master)
* Added **WMS support** (`TileLayer.WMS`).
* Improved different projections support (through `crs` option in `Map`).
* Improved **different projections support**, having `EPSG:3857`, `EPSG:4326` and `EPSG:3395` out of the box (through `crs` option in `Map`).
* Added `TileLayer.Canvas` for easy creation of canvas-based tile layers.
* `Circle` is now zoom-dependent (with radius in meters); circle of a permanent size is now called `L.CircleMarker`.
* Added `mouseover` and `mouseout` events to map, markers and paths; added map `mousemove` event.

View File

@ -19,8 +19,14 @@
--js ../src/dom/transition/Transition.Timer.js \
--js ../src/geo/LatLng.js \
--js ../src/geo/LatLngBounds.js \
--js ../src/geo/Projection.js \
--js ../src/geo/CRS.js \
--js ../src/geo/projection/Projection.js \
--js ../src/geo/projection/Projection.SphericalMercator.js \
--js ../src/geo/projection/Projection.LonLat.js \
--js ../src/geo/projection/Projection.Mercator.js \
--js ../src/geo/crs/CRS.js \
--js ../src/geo/crs/CRS.EPSG3857.js \
--js ../src/geo/crs/CRS.EPSG4326.js \
--js ../src/geo/crs/CRS.EPSG3395.js \
--js ../src/layer/tile/TileLayer.js \
--js ../src/layer/tile/TileLayer.WMS.js \
--js ../src/layer/tile/TileLayer.Canvas.js \

View File

@ -19,8 +19,14 @@ java -jar ../lib/closure-compiler/compiler.jar ^
--js ../src/dom/transition/Transition.Timer.js ^
--js ../src/geo/LatLng.js ^
--js ../src/geo/LatLngBounds.js ^
--js ../src/geo/Projection.js ^
--js ../src/geo/CRS.js ^
--js ../src/geo/projection/Projection.js ^
--js ../src/geo/projection/Projection.SphericalMercator.js ^
--js ../src/geo/projection/Projection.LonLat.js ^
--js ../src/geo/projection/Projection.Mercator.js ^
--js ../src/geo/crs/CRS.js ^
--js ../src/geo/crs/CRS.EPSG3857.js ^
--js ../src/geo/crs/CRS.EPSG4326.js ^
--js ../src/geo/crs/CRS.EPSG3395.js ^
--js ../src/layer/tile/TileLayer.js ^
--js ../src/layer/tile/TileLayer.WMS.js ^
--js ../src/layer/tile/TileLayer.Canvas.js ^

View File

@ -8,16 +8,27 @@ var deps = {
'dom/DomUtil.js',
'geo/LatLng.js',
'geo/LatLngBounds.js',
'geo/Projection.js',
'geo/CRS.js',
'geo/projection/Projection.js',
'geo/projection/Projection.SphericalMercator.js',
'geo/projection/Projection.LonLat.js',
'geo/crs/CRS.js',
'geo/crs/CRS.EPSG3857.js',
'geo/crs/CRS.EPSG4326.js',
'geometry/Bounds.js',
'geometry/Point.js',
'geometry/Transformation.js',
'map/Map.js'],
desc: 'The core of the library, including OOP, events, DOM facilities, basic units, projections and the base Map class.'
desc: 'The core of the library, including OOP, events, DOM facilities, basic units, projections (EPSG:3857 and EPSG:4326) and the base Map class.'
},
EPSG3395: {
src: ['geo/projection/Projection.Mercator.js',
'geo/crs/CRS.EPSG3395.js'],
desc: 'EPSG:3395 projection (used by some map providers).',
heading: 'Additional projections'
},
TileLayer: {
src: ['layer/tile/TileLayer.js'],
desc: 'The base class for displaying tile layers on the map.',

View File

@ -25,8 +25,16 @@
'geo/LatLng.js',
'geo/LatLngBounds.js',
'geo/Projection.js',
'geo/CRS.js',
'geo/projection/Projection.js',
'geo/projection/Projection.SphericalMercator.js',
'geo/projection/Projection.LonLat.js',
'geo/projection/Projection.Mercator.js',
'geo/crs/CRS.js',
'geo/crs/CRS.EPSG3857.js',
'geo/crs/CRS.EPSG4326.js',
'geo/crs/CRS.EPSG3395.js',
'layer/tile/TileLayer.js',
'layer/tile/TileLayer.WMS.js',

View File

@ -15,7 +15,7 @@
<div id="map" style="width: 1024px; height: 440px; border: 1px solid #ccc"></div>
<script type="text/javascript">
var map = new L.Map('map', {crs: new L.CRS.EPSG4326()});
var map = new L.Map('map', {crs: L.CRS.EPSG4326});
var bluemarble = new L.TileLayer.WMS("http://maps.opengeo.org/geowebcache/service/wms", {
layers: 'bluemarble',
@ -24,8 +24,6 @@
maxZoom: 5,
});
var bounds = new L.LatLngBounds(new L.LatLng(32, -126), new L.LatLng(50, -64));
map.addLayer(bluemarble).fitWorld();
</script>
</body>

9
dist/leaflet.js vendored
View File

@ -33,9 +33,8 @@ new L.Point(0,0);this._p2=new L.Point(c[0],c[1]);this._p3=new L.Point(c[2],c[3])
this._timer=setInterval(this._step,this._interval);this._startTime=L.Transition.getTime()},_step:function(){var a=L.Transition.getTime()-this._startTime,b=this.options.duration*1E3;a<b?this._runFrame(this._cubicBezier(a/b)):(this._runFrame(1),this._complete())},_runFrame:function(a){var b=L.Transition.CUSTOM_PROPS_SETTERS,c,d;for(c in this._props)this._props.hasOwnProperty(c)&&(d=this._props[c],c in b?(d=d.to.subtract(d.from).multiplyBy(a).add(d.from),b[c](this._el,d)):this._el.style[c]=(d.to-d.from)*
a+d.from+d.unit);this.fire("step")},_complete:function(){clearInterval(this._timer);this.fire("end")},_cubicBezier:function(a){var b=3*Math.pow(1-a,2)*a,c=3*(1-a)*Math.pow(a,2),d=Math.pow(a,3),a=this._p1.multiplyBy(Math.pow(1-a,3)),b=this._p2.multiplyBy(b),c=this._p3.multiplyBy(c),d=this._p4.multiplyBy(d);return a.add(b).add(c).add(d).y}});L.LatLng=function(a,b,c){c!==!0&&(a=Math.max(Math.min(a,90),-90),b=(b+180)%360+(b<-180?180:-180));this.lat=a;this.lng=b};L.Util.extend(L.LatLng,{DEG_TO_RAD:Math.PI/180,RAD_TO_DEG:180/Math.PI,MAX_MARGIN:1.0E-9});L.LatLng.prototype={equals:function(a){if(!(a instanceof L.LatLng))return!1;return Math.max(Math.abs(this.lat-a.lat),Math.abs(this.lng-a.lng))<=L.LatLng.MAX_MARGIN},toString:function(){return"LatLng("+L.Util.formatNum(this.lat)+", "+L.Util.formatNum(this.lng)+")"}};L.LatLngBounds=L.Class.extend({initialize:function(a,b){for(var c=a instanceof Array?a:[a,b],d=0,e=c.length;d<e;d++)this.extend(c[d])},extend:function(a){!this._southWest&&!this._northEast?(this._southWest=new L.LatLng(a.lat,a.lng),this._northEast=new L.LatLng(a.lat,a.lng)):(this._southWest.lat=Math.min(a.lat,this._southWest.lat),this._southWest.lng=Math.min(a.lng,this._southWest.lng),this._northEast.lat=Math.max(a.lat,this._northEast.lat),this._northEast.lng=Math.max(a.lng,this._northEast.lng))},
getCenter:function(){return new L.LatLng((this._southWest.lat+this._northEast.lat)/2,(this._southWest.lng+this._northEast.lng)/2)},getSouthWest:function(){return this._southWest},getNorthEast:function(){return this._northEast},getNorthWest:function(){return new L.LatLng(this._northEast.lat,this._southWest.lng)},getSouthEast:function(){return new L.LatLng(this._southWest.lat,this._northEast.lng)},contains:function(a){var b=this._southWest,c=this._northEast,d;a instanceof L.LatLngBounds?(d=a.getSouthWest(),
a=a.getNorthEast()):d=a;return d.lat>=b.lat&&a.lat<=c.lat&&d.lng>=b.lng&&a.lng<=c.lng}});L.Projection={};L.Projection.Mercator={MAX_LATITUDE:function(){var a=Math.exp(2*Math.PI);return Math.asin((a-1)/(a+1))*L.LatLng.RAD_TO_DEG}(),project:function(a){var b=L.LatLng.DEG_TO_RAD,c=L.Projection.Mercator.MAX_LATITUDE,d=a.lng*b,a=Math.max(Math.min(c,a.lat),-c)*b,a=Math.log(Math.tan(Math.PI/4+a/2));return new L.Point(d,a)},unproject:function(a,b){var c=L.LatLng.RAD_TO_DEG;return new L.LatLng((2*Math.atan(Math.exp(a.y))-Math.PI/2)*c,a.x*c,b)}};
L.Projection.LonLat={project:function(a){return new L.Point(a.lng,a.lat)},unproject:function(a,b){return new L.LatLng(a.y,a.x,b)}};L.CRS=L.Class.extend({latLngToPoint:function(a,b){return this.transformation._transform(this.projection.project(a),b)},pointToLatLng:function(a,b,c){return this.projection.unproject(this.transformation.untransform(a,b),c)},project:L.Projection.LonLat.project});L.CRS.EPSG4326=L.CRS.extend({code:"EPSG:4326",projection:L.Projection.LonLat,transformation:new L.Transformation(1/360,0.5,-1/360,0.5)});
L.CRS.EPSG3857=L.CRS.extend({code:"EPSG:3857",projection:L.Projection.Mercator,transformation:new L.Transformation(0.5/Math.PI,0.5,-0.5/Math.PI,0.5),project:function(a){return this.projection.project(a).multiplyBy(6378137)}});L.CRS.EPSG3395=L.CRS.EPSG3857.extend({code:"EPSG:3395"});L.TileLayer=L.Class.extend({includes:L.Mixin.Events,options:{minZoom:0,maxZoom:18,tileSize:256,subdomains:"abc",errorTileUrl:"",attribution:"",opacity:1,scheme:"xyz",unloadInvisibleTiles:L.Browser.mobileWebkit,updateWhenIdle:L.Browser.mobileWebkit},initialize:function(a,b){L.Util.setOptions(this,b);this._url=a;if(typeof this.options.subdomains=="string")this.options.subdomains=this.options.subdomains.split("")},onAdd:function(a){this._map=a;this._initContainer();this._createTileProto();a.on("viewreset",
a=a.getNorthEast()):d=a;return d.lat>=b.lat&&a.lat<=c.lat&&d.lng>=b.lng&&a.lng<=c.lng}});L.Projection={};L.Projection.SphericalMercator={MAX_LATITUDE:85.0511287798,project:function(a){var b=L.LatLng.DEG_TO_RAD,c=this.MAX_LATITUDE,d=a.lng*b,a=Math.max(Math.min(c,a.lat),-c)*b,a=Math.log(Math.tan(Math.PI/4+a/2));return new L.Point(d,a)},unproject:function(a,b){var c=L.LatLng.RAD_TO_DEG;return new L.LatLng((2*Math.atan(Math.exp(a.y))-Math.PI/2)*c,a.x*c,b)}};L.Projection.LonLat={project:function(a){return new L.Point(a.lng,a.lat)},unproject:function(a,b){return new L.LatLng(a.y,a.x,b)}};L.Projection.Mercator={MAX_LATITUDE:85.0840591556,R_MINOR:6356752.3142,R_MAJOR:6378137,project:function(a){var b=L.LatLng.DEG_TO_RAD,c=this.MAX_LATITUDE,d=this.R_MAJOR,e=a.lng*b*d,a=Math.max(Math.min(c,a.lat),-c)*b,b=this.R_MINOR/d,b=Math.sqrt(1-b*b),c=b*Math.sin(a),c=Math.pow((1-c)/(1+c),b*0.5),a=-d*Math.log(Math.tan(0.5*(Math.PI*0.5-a))/c);return new L.Point(e,a)},unproject:function(a,b){for(var c=L.LatLng.RAD_TO_DEG,d=this.R_MAJOR,e=a.x*c/d,f=this.R_MINOR/d,f=Math.sqrt(1-f*f),d=Math.exp(-a.y/d),
g=Math.PI/2-2*Math.atan(d),h=15,i=0.1;Math.abs(i)>1.0E-7&&--h>0;)i=f*Math.sin(g),i=Math.PI/2-2*Math.atan(d*Math.pow((1-i)/(1+i),0.5*f))-g,g+=i;return new L.LatLng(g*c,e,b)}};L.CRS={latLngToPoint:function(a,b){return this.transformation._transform(this.projection.project(a),b)},pointToLatLng:function(a,b,c){return this.projection.unproject(this.transformation.untransform(a,b),c)},project:function(a){return this.projection.project(a)}};L.CRS.EPSG3857=L.Util.extend({},L.CRS,{code:"EPSG:3857",projection:L.Projection.SphericalMercator,transformation:new L.Transformation(0.5/Math.PI,0.5,-0.5/Math.PI,0.5),project:function(a){return this.projection.project(a).multiplyBy(6378137)}});L.CRS.EPSG900913=L.Util.extend({},L.CRS.EPSG3857,{code:"EPSG:900913"});L.CRS.EPSG4326=L.Util.extend({},L.CRS,{code:"EPSG:4326",projection:L.Projection.LonLat,transformation:new L.Transformation(1/360,0.5,-1/360,0.5)});L.CRS.EPSG3395=L.Util.extend({},L.CRS,{code:"EPSG:3395",projection:L.Projection.Mercator,transformation:function(){var a=L.Projection.Mercator;return new L.Transformation(0.5/(Math.PI*a.R_MAJOR),0.5,-0.5/(Math.PI*a.R_MINOR),0.5)}()});L.TileLayer=L.Class.extend({includes:L.Mixin.Events,options:{minZoom:0,maxZoom:18,tileSize:256,subdomains:"abc",errorTileUrl:"",attribution:"",opacity:1,scheme:"xyz",unloadInvisibleTiles:L.Browser.mobileWebkit,updateWhenIdle:L.Browser.mobileWebkit},initialize:function(a,b){L.Util.setOptions(this,b);this._url=a;if(typeof this.options.subdomains=="string")this.options.subdomains=this.options.subdomains.split("")},onAdd:function(a){this._map=a;this._initContainer();this._createTileProto();a.on("viewreset",
this._reset,this);if(this.options.updateWhenIdle)a.on("moveend",this._update,this);else this._limitedUpdate=L.Util.limitExecByInterval(this._update,100,this),a.on("move",this._limitedUpdate,this);this._reset();this._update()},onRemove:function(){this._map.getPanes().tilePane.removeChild(this._container);this._map.off("viewreset",this._reset);this.options.updateWhenIdle?this._map.off("moveend",this._update):this._map.off("move",this._limitedUpdate)},getAttribution:function(){return this.options.attribution},
_initContainer:function(){var a=this._map.getPanes().tilePane;if(!this._container||a.empty)this._container=L.DomUtil.create("div","leaflet-layer",a),this.options.opacity<1&&L.DomUtil.setOpacity(this._container,this.options.opacity)},_reset:function(){this._tiles={};this._initContainer();this._container.innerHTML=""},_update:function(){var a=this._map.getPixelBounds(),b=this.options.tileSize,c=new L.Point(Math.floor(a.min.x/b),Math.floor(a.min.y/b)),a=new L.Point(Math.floor(a.max.x/b),Math.floor(a.max.y/
b)),c=new L.Bounds(c,a);this._addTilesFromCenterOut(c);this.options.unloadInvisibleTiles&&this._removeOtherTiles(c)},_addTilesFromCenterOut:function(a){for(var b=[],c=a.getCenter(),d=a.min.y;d<=a.max.y;d++)for(var e=a.min.x;e<=a.max.x;e++)e+":"+d in this._tiles||b.push(new L.Point(e,d));b.sort(function(a,b){return a.distanceTo(c)-b.distanceTo(c)});this._tilesToLoad=b.length;a=0;for(d=this._tilesToLoad;a<d;a++)this._addTile(b[a])},_removeOtherTiles:function(a){var b,c,d;for(d in this._tiles)if(this._tiles.hasOwnProperty(d)&&
@ -78,8 +77,8 @@ b=new L.Point(Math.min(b.x,this._startLayerPoint.x),Math.min(b.y,this._startLaye
this._map.layerPointToLatLng(a)))}});L.Handler.MarkerDrag=L.Handler.extend({initialize:function(a){this._marker=a},enable:function(){if(!this._enabled){if(!this._draggable)this._draggable=new L.Draggable(this._marker._icon,this._marker._icon),this._draggable.on("dragstart",this._onDragStart,this),this._draggable.on("drag",this._onDrag,this),this._draggable.on("dragend",this._onDragEnd,this);this._draggable.enable();this._enabled=!0}},disable:function(){if(this._enabled)this._draggable.disable(),this._enabled=!1},moved:function(){return this._draggable&&
this._draggable._moved},_onDragStart:function(){this._marker.closePopup();this._marker.fire("movestart");this._marker.fire("dragstart")},_onDrag:function(){var a=L.DomUtil.getPosition(this._marker._icon);L.DomUtil.setPosition(this._marker._shadow,a);this._marker._latlng=this._marker._map.layerPointToLatLng(a);this._marker.fire("move");this._marker.fire("drag")},_onDragEnd:function(){this._marker.fire("moveend");this._marker.fire("dragend")}});L.Control={};L.Control.Position={TOP_LEFT:"topLeft",TOP_RIGHT:"topRight",BOTTOM_LEFT:"bottomLeft",BOTTOM_RIGHT:"bottomRight"};L.Control.Zoom=L.Class.extend({onAdd:function(a){this._map=a;this._container=L.DomUtil.create("div","leaflet-control-zoom");this._zoomInButton=this._createButton("Zoom in","leaflet-control-zoom-in",this._map.zoomIn,this._map);this._zoomOutButton=this._createButton("Zoom out","leaflet-control-zoom-out",this._map.zoomOut,this._map);this._container.appendChild(this._zoomInButton);this._container.appendChild(this._zoomOutButton)},getContainer:function(){return this._container},getPosition:function(){return L.Control.Position.TOP_LEFT},
_createButton:function(a,b,c,d){var e=document.createElement("a");e.href="#";e.title=a;e.className=b;L.DomEvent.disableClickPropagation(e);L.DomEvent.addListener(e,"click",L.DomEvent.preventDefault);L.DomEvent.addListener(e,"click",c,d);return e}});L.Control.Attribution=L.Class.extend({onAdd:function(a){this._container=L.DomUtil.create("div","leaflet-control-attribution");this._map=a;this._prefix='Powered by <a href="http://leaflet.cloudmade.com">Leaflet</a>';this._attributions={};this._update()},getPosition:function(){return L.Control.Position.BOTTOM_RIGHT},getContainer:function(){return this._container},setPrefix:function(a){this._prefix=a},addAttribution:function(a){a&&(this._attributions[a]=!0,this._update())},removeAttribution:function(a){a&&
(delete this._attributions[a],this._update())},_update:function(){if(this._map){var a=[],b;for(b in this._attributions)this._attributions.hasOwnProperty(b)&&a.push(b);this._container.innerHTML=[this._prefix,a.join(", ")].join(" &mdash; ")}}});L.Map=L.Class.extend({includes:L.Mixin.Events,options:{crs:new L.CRS.EPSG3857,scale:function(a){return 256*(1<<a)},center:null,zoom:null,layers:[],dragging:!0,touchZoom:L.Browser.mobileWebkit&&!L.Browser.android,scrollWheelZoom:!L.Browser.mobileWebkit,doubleClickZoom:!0,shiftDragZoom:!0,zoomControl:!0,attributionControl:!0,fadeAnimation:L.DomUtil.TRANSITION&&!L.Browser.android,zoomAnimation:L.DomUtil.TRANSITION&&!L.Browser.android,trackResize:!0,closePopupOnClick:!0},initialize:function(a,b){L.Util.setOptions(this,
b);this._container=L.DomUtil.get(a);this._initLayout();L.DomEvent&&(this._initEvents(),L.Handler&&this._initInteraction(),L.Control&&this._initControls());var c=this.options.center,d=this.options.zoom;c!==null&&d!==null&&this.setView(c,d,!0);c=this.options.layers;c=c instanceof Array?c:[c];this._tileLayersNum=0;this._initLayers(c)},setView:function(a,b){this._resetView(a,this._limitZoom(b));return this},setZoom:function(a){return this.setView(this.getCenter(),a)},zoomIn:function(){return this.setZoom(this._zoom+
(delete this._attributions[a],this._update())},_update:function(){if(this._map){var a=[],b;for(b in this._attributions)this._attributions.hasOwnProperty(b)&&a.push(b);this._container.innerHTML=[this._prefix,a.join(", ")].join(" &mdash; ")}}});L.Map=L.Class.extend({includes:L.Mixin.Events,options:{crs:L.CRS.EPSG3857||L.CRS.EPSG4326,scale:function(a){return 256*(1<<a)},center:null,zoom:null,layers:[],dragging:!0,touchZoom:L.Browser.mobileWebkit&&!L.Browser.android,scrollWheelZoom:!L.Browser.mobileWebkit,doubleClickZoom:!0,shiftDragZoom:!0,zoomControl:!0,attributionControl:!0,fadeAnimation:L.DomUtil.TRANSITION&&!L.Browser.android,zoomAnimation:L.DomUtil.TRANSITION&&!L.Browser.android,trackResize:!0,closePopupOnClick:!0},initialize:function(a,
b){L.Util.setOptions(this,b);this._container=L.DomUtil.get(a);this._initLayout();L.DomEvent&&(this._initEvents(),L.Handler&&this._initInteraction(),L.Control&&this._initControls());var c=this.options.center,d=this.options.zoom;c!==null&&d!==null&&this.setView(c,d,!0);c=this.options.layers;c=c instanceof Array?c:[c];this._tileLayersNum=0;this._initLayers(c)},setView:function(a,b){this._resetView(a,this._limitZoom(b));return this},setZoom:function(a){return this.setView(this.getCenter(),a)},zoomIn:function(){return this.setZoom(this._zoom+
1)},zoomOut:function(){return this.setZoom(this._zoom-1)},fitBounds:function(a){var b=this.getBoundsZoom(a);return this.setView(a.getCenter(),b)},fitWorld:function(){var a=new L.LatLng(-60,-170),b=new L.LatLng(85,179);return this.fitBounds(new L.LatLngBounds(a,b))},panTo:function(a){return this.setView(a,this._zoom)},panBy:function(a){this.fire("movestart");this._rawPanBy(a);this.fire("move");this.fire("moveend");return this},addLayer:function(a){var b=L.Util.stamp(a);if(this._layers[b])return this;
this._layers[b]=a;if(a.options&&!isNaN(a.options.maxZoom))this._layersMaxZoom=Math.max(this._layersMaxZoom||0,a.options.maxZoom);if(a.options&&!isNaN(a.options.minZoom))this._layersMinZoom=Math.min(this._layersMinZoom||Infinity,a.options.minZoom);this.options.zoomAnimation&&L.TileLayer&&a instanceof L.TileLayer&&(this._tileLayersNum++,a.on("load",this._onTileLayerLoad,this));this.attributionControl&&a.getAttribution&&this.attributionControl.addAttribution(a.getAttribution());b=function(){a.onAdd(this);
this.fire("layeradd",{layer:a})};if(this._loaded)b.call(this);else this.on("load",b,this);return this},removeLayer:function(a){var b=L.Util.stamp(a);this._layers[b]&&(a.onRemove(this),delete this._layers[b],this.options.zoomAnimation&&L.TileLayer&&a instanceof L.TileLayer&&this._tileLayersNum--,this.attributionControl&&a.getAttribution&&this.attributionControl.removeAttribution(a.getAttribution()),this.fire("layerremove",{layer:a}));return this},invalidateSize:function(){this._sizeChanged=!0;this.fire("move");

View File

@ -1,36 +0,0 @@
L.CRS = L.Class.extend({
latLngToPoint: function(/*LatLng*/ latlng, /*Number*/ scale)/*-> Point*/ {
var projectedPoint = this.projection.project(latlng);
return this.transformation._transform(projectedPoint, scale);
},
pointToLatLng: function(/*Point*/ point, /*Number*/ scale, /*(optional) Boolean*/ unbounded)/*-> LatLng*/ {
var untransformedPoint = this.transformation.untransform(point, scale);
return this.projection.unproject(untransformedPoint, unbounded);
//TODO get rid of 'unbounded' everywhere
},
project: L.Projection.LonLat.project
});
L.CRS.EPSG4326 = L.CRS.extend({
code: 'EPSG:4326',
projection: L.Projection.LonLat,
transformation: new L.Transformation(1/360, 0.5, -1/360, 0.5)
});
L.CRS.EPSG3857 = L.CRS.extend({
code: 'EPSG:3857',
projection: L.Projection.Mercator,
transformation: new L.Transformation(0.5/Math.PI, 0.5, -0.5/Math.PI, 0.5),
project: function(/*LatLng*/ latlng)/*-> Point*/ {
var projectedPoint = this.projection.project(latlng),
earthRadius = 6378137;
return projectedPoint.multiplyBy(earthRadius);
}
});
L.CRS.EPSG3395 = L.CRS.EPSG3857.extend({
code: 'EPSG:3395'
});

View File

@ -1,43 +0,0 @@
/*
* L.Projection contains various geographical projections.
*/
L.Projection = {};
//Mercator Projection - see http://en.wikipedia.org/wiki/Mercator_projection
L.Projection.Mercator = {
MAX_LATITUDE: (function() {
var a = Math.exp(2 * Math.PI);
return Math.asin((a - 1)/(a + 1)) * L.LatLng.RAD_TO_DEG;
})(),
project: function(/*LatLng*/ latlng) /*-> Point*/ {
var d = L.LatLng.DEG_TO_RAD,
max = L.Projection.Mercator.MAX_LATITUDE,
lat = Math.max(Math.min(max, latlng.lat), -max),
x = latlng.lng * d,
y = lat * d;
y = Math.log(Math.tan(Math.PI/4 + y/2));
return new L.Point(x, y);
},
unproject: function(/*Point*/ point, /*Boolean*/ unbounded) /*-> LatLng*/ {
var d = L.LatLng.RAD_TO_DEG,
lng = point.x * d,
lat = (2 * Math.atan(Math.exp(point.y)) - Math.PI/2) * d;
return new L.LatLng(lat, lng, unbounded);
}
};
L.Projection.LonLat = {
project: function(latlng) {
return new L.Point(latlng.lng, latlng.lat);
},
unproject: function(point, unbounded) {
return new L.LatLng(point.y, point.x, unbounded);
}
};

View File

@ -0,0 +1,13 @@
L.CRS.EPSG3395 = L.Util.extend({}, L.CRS, {
code: 'EPSG:3395',
projection: L.Projection.Mercator,
transformation: (function() {
var m = L.Projection.Mercator,
r = m.R_MAJOR,
r2 = m.R_MINOR;
return new L.Transformation(0.5/(Math.PI * r), 0.5, -0.5/(Math.PI * r2), 0.5);
})()
});

View File

@ -0,0 +1,17 @@
L.CRS.EPSG3857 = L.Util.extend({}, L.CRS, {
code: 'EPSG:3857',
projection: L.Projection.SphericalMercator,
transformation: new L.Transformation(0.5/Math.PI, 0.5, -0.5/Math.PI, 0.5),
project: function(/*LatLng*/ latlng)/*-> Point*/ {
var projectedPoint = this.projection.project(latlng),
earthRadius = 6378137;
return projectedPoint.multiplyBy(earthRadius);
}
});
L.CRS.EPSG900913 = L.Util.extend({}, L.CRS.EPSG3857, {
code: 'EPSG:900913'
});

View File

@ -0,0 +1,7 @@
L.CRS.EPSG4326 = L.Util.extend({}, L.CRS, {
code: 'EPSG:4326',
projection: L.Projection.LonLat,
transformation: new L.Transformation(1/360, 0.5, -1/360, 0.5)
});

17
src/geo/crs/CRS.js Normal file
View File

@ -0,0 +1,17 @@
L.CRS = {
latLngToPoint: function(/*LatLng*/ latlng, /*Number*/ scale)/*-> Point*/ {
var projectedPoint = this.projection.project(latlng);
return this.transformation._transform(projectedPoint, scale);
},
pointToLatLng: function(/*Point*/ point, /*Number*/ scale, /*(optional) Boolean*/ unbounded)/*-> LatLng*/ {
var untransformedPoint = this.transformation.untransform(point, scale);
return this.projection.unproject(untransformedPoint, unbounded);
//TODO get rid of 'unbounded' everywhere
},
project: function(latlng) {
return this.projection.project(latlng);
}
};

View File

@ -0,0 +1,5 @@
/*
* L.Projection contains various geographical projections used by CRS classes.
*/
L.Projection = {};

View File

@ -7,7 +7,7 @@ L.Map = L.Class.extend({
options: {
// projection
crs: new L.CRS.EPSG3857(),
crs: L.CRS.EPSG3857 || L.CRS.EPSG4326,
scale: function(zoom) { return 256 * (1 << zoom); },
// state