Custom CRS custom meter scale for circle layers?

486 views
Skip to first unread message

dnjord

unread,
Feb 27, 2015, 7:01:34 PM2/27/15
to leafl...@googlegroups.com
I'm trying to use Leaflet to display a game map for Arma 3, which includes its own coordinate system. Ideally, this coordinate system can be synchronized with the coordinate system in the Leaflet map so that given game coordinates will map perfectly to the same position on the Leaflet map. The game coordinate system starts at 0,0 in the bottom left and both values increase as you move up and right (northeast). I had to account for the fact that the map I have doesn't start at exactly point 0,0 (the map creator cut out part of the map because it was empty ocean) and the map scale doesn't match up perfectly to the CRS.Simple latitude and longitude numbers.

I've got this essentially working through a custom CRS with one exception: when I add circles to the map, the radius appears to be incredibly small no matter what value I pass. I imagine this has something to do with Leaflet assuming there's 111km between each increment of x or y, but my map is scaled to 100m between each x or y. Is there any way to fix this? The important piece is being able to maintain coordinates and specify markers using the in-game coordinate system.

Here it is in action, and here's my code:
<div id="map"></div>
<script>
   
// Custom CRS
    L
.CRS.Arma = L.extend({}, L.CRS, {
        projection
: L.Projection.LonLat,
        transformation
: new L.Transformation(1, 0, -1, 0),
        scale
: function (zoom) {
           
return Math.pow(2, zoom);
       
},
        latLngToPoint
: function(latlng, zoom) {
           
var adjlatlng = L.latLng((latlng.lat-this.adjust.y)/this.adjust.scale.y, (latlng.lng-this.adjust.x)/this.adjust.scale.x);
           
return L.CRS.Simple.latLngToPoint(adjlatlng, zoom);
       
},
        pointToLatLng
: function(point, zoom) {
           
var latlng = L.CRS.Simple.pointToLatLng(point, zoom);
            latlng
.lng = (latlng.lng*this.adjust.scale.x)+this.adjust.x;
            latlng
.lat = (latlng.lat*this.adjust.scale.y)+this.adjust.y;
           
return latlng;
       
},
        adjust
: {
            x
: 0.3,
            y
: 25.4,
            scale
: {
                x
: 2.3275,
                y
: 2.3275
           
}
       
}
   
});

   
var map = L.map('map', {
        zoomControl
: false,
        crs
: L.CRS.Arma
   
});
    L
.tileLayer('http://badkarmagaming.com/wp-content/plugins/arma-maps/maps/AltisZL5/{z}/{x}/{y}.png', {
        maxZoom
: 7,
        minZoom
: 2,
        attribution
: 'Web Map by <a href="http://forums.bistudio.com/showthread.php?178671-Tiled-maps-Google-maps-compatible-%28WIP%29">10T</a> (adapted by Razzmatazz), Altis by Bohemia Interactive',
        noWrap
: true,
        tms
: true,
        continuousWorld
: true
   
}).addTo(map);
    map
.setView([145, 133.5], 3);

   
new L.Control.Zoom({ position: 'topleft' }).addTo(map);

    L
.circle([145, 133.5], 300, {
        color
: 'green',
        fillColor
: '#0f3',
        fillOpacity
: 0.6
   
}).addTo(map).bindPopup("<b>Safe zone traders</b>");
   
   
var popup = L.popup();
   
function onMapClick(e) {
       
var x = e.latlng.lng.toFixed(1);
       
var y = e.latlng.lat.toFixed(1);

        popup
           
.setLatLng(e.latlng)
           
.setContent(e.latlng.toString()+'<br>x: '+x+', y: '+y)
           
.openOn(map);
   
}
    map
.on('contextmenu', onMapClick);
</script>

Any help you can provide would be greatly appreciated.

Thanks.
Message has been deleted
Message has been deleted
Message has been deleted

LtIIsidII HQ

unread,
Feb 27, 2015, 8:01:30 PM2/27/15
to leafl...@googlegroups.com
var myIcon = L.icon({
    iconSize: [32, 37],
    iconAnchor: [24, 36],
    popupAnchor: [-3, -38],
    //shadowUrl: 'my-icon-shadow.png',
    //shadowRetinaUrl: 'my-icon-shadow.png',
    //shadowSize: [68, 95],
    //shadowAnchor: [22, 94]
});

    L.marker([145, 133.5], {icon: myIcon}).addTo(map).bindPopup("<b>Safe zone traders</b>");
Message has been deleted

dnjord

unread,
Mar 8, 2015, 9:15:08 PM3/8/15
to leafl...@googlegroups.com
If anyone else has this problem, I solved it by extending the Circle class:

L.MyCircle = L.Circle.extend({
    initialize
: function (latlng, radius, options) {
        L
.Circle.prototype.initialize.call(this, latlng, radius, options);
   
},

    getBounds
: function () {
       
var lngRadius = this._getLngRadius(),
            latRadius
= this._getLatRadius(),
            latlng
= this._latlng;

       
return new L.LatLngBounds(
               
[latlng.lat - latRadius, latlng.lng - lngRadius],
               
[latlng.lat + latRadius, latlng.lng + lngRadius]);
   
},

    _getLatRadius
: function () {
       
return (this._mRadius / 100.0);
   
},

    _getLngRadius
: function () {
       
return this._getLatRadius();
   
}
});

L
.myCircle = function (latlng, radius, options) {
   
return new L.MyCircle(latlng, radius, options);
};
Reply all
Reply to author
Forward
0 new messages