Mapstraction - draw polygon dynamically - javascript

In Mapstraction map need to draw a polygon which is editable.
So i have tried a example.
But polygon is editable mode while it's calling function href="javascript:mapstraction.activateEdition();" in example.
I have tried to do that. Didn't get succeed.
How do i create polygon which user can edit it and also is this possible to keep only 10 vertices polygon.
JS Code
var polyPoint;
var polyPoints = []
//Adding polygon to map
polyPoint = new mxn.LatLonPoint(17.447612 , 78.223686)
polyPoints.push(polyPoint);
polyPoint = new mxn.LatLonPoint(17.504593 , 78.306084)
polyPoints.push(polyPoint);
polyPoint = new mxn.LatLonPoint(17.471193 , 78.417320)
polyPoints.push(polyPoint);
polyPoint = new mxn.LatLonPoint(17.414201 , 78.470879)
polyPoints.push(polyPoint);
var polygon = new mxn.Polyline(polyPoints);
polygon.setClosed(true);
map.addPolyline(polygon)
//Adding event listeners to map
mapstraction.markerChanged.addHandler(function(event,map,marker){
alert('Marker moved to: '+marker.marker.location.lat+' , '+marker.marker.location.lon)})
mapstraction.polylineChanged.addHandler(function(event,map,polyline){
alert('Polyline modified: Now it has '+polyline.polyline.points.length+' vertices')})

That example is for the idelab fork of Mapstraction so you need to ensure you're using that version which you can get from here:
https://github.com/idelab/mxn
I'm not sure whether the idelab version is still supported and I think OpenLayers API has changed since it was initially developed so, if you are using the correct version, that could be why you're having problems.
I'm afraid editable maps are not supported in the trunk version of Mapstraction. Primarily because not all the map providers support it so it would be less useful as part of Mapstraction. Also because most people don't require it so its difficult to justify the effort of adding it to the library.
If you are using OpenLayers and don't need to be able to switch provider you should consider programming directly against the OpenLayers API. If you do need to be able to switch provider you should contact the owner of the idelab repo (plopesc) and check whether it supports your use case.

Related

Open Layers 2 Creating and adding Feature to Vector Layer from Ajax Response

as title suggest, create Feature and add it to already created vector layer. I am fetching GeoJSON from server and trying to somehow add to vector layer but I can't get it to work... So basically I am asking how to get Feature element from my GeoJSON, so I can add it to vector layer.
What I currently have..
This is my GeoJSON fetched from server :
{"type":"MultiPolygon","coordinates":[[[[20.5629940201429,48.9488601183337],[20.5630121528311,48.9489447276126],[20.563289335522,48.9489141101973],[20.563260061873,48.9488286413488],[20.5629940201429,48.9488601183337]]]]}
next I have addVector function in JavaScript where I'm trying to the magic.(variable GeoJS is GeoJSON fetched from server)
function addVector(geoJS){
var feature = new OpenLayers.Feature.Vector( new OpenLayers.Geometry.MultiPolygon(geoJS) );
vector = new OpenLayers.Layer.Vector("Magic");
map.addLayer(vector);
vector.addFeatures([feature]);
}
and yep I know that second line where I creating feature is wrong, but i cant make it right so i guess id doesn't matter what I write there for now...
I tried it with var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(-70.702451, 42.374473); and it worked position on the map was not where I want it to be but I know that i have to do something with projection... It just doesn't matter now.
and btw I have this
vector = new OpenLayers.Layer.Vector("GeoJSON",
{
projection : "EPSG:4326",
onFeatureInsert : postIns,
strategies : [new OpenLayers.Strategy.Fixed()],
protocol : new OpenLayers.Protocol.HTTP({
url: "test.php",
format: new OpenLayers.Format.GeoJSON()
})
});
And this works, position is where I want it, its perfect except it only works when I make request on my domain, and server I try to reach is on another(I know I can set headers and it would work) but I don't want to do it this way.
So basically I am asking how to get Feature from my GeoJSON. I am really new to OpenLayers so I'm sorry if I asking something obvious.
To use a simplified version of the official example:
var inputGeoJson = '...some-GeoJSON-here...';
var geojson_format = new OpenLayers.Format.GeoJSON();
var vector_layer = new OpenLayers.Layer.Vector();
map.addLayer(vector_layer);
vector_layer.addFeatures(geojson_format.read(inputGeoJson));
You can find more details in the GeoJSON class documentation.

Offer packages of map tiles for offline use

I'm making a web application that has to work offline. So far everything works and my last step is to take the map tiles offline. Luckily I know exactly what areas of the map will need to be accessible to users, so I don't have to allow caching of millions of tiles.
The map is split into areas and so the idea is to offer the tiles for these areas as downloadable 'packages.'
For instance, when I'm online, I go to the 'tile packages' page, which offers downloads for several areas. I choose the area which I'm interested in, it downloads the tiles, and when I go offline, I'm able to use these tiles. I only need about 2 zoom levels, one far out for quick navigation, and one more up close for more detail.
I'm using leaflet to serve up the map. Has anyone had to do something like this and could give me some guidance? I really just don't know how to even approach this, and it's the last piece of the puzzle.
Sadly you don't point out, what the exact problem is or at which step you fail. So I will try to give a general answer:
Leaflet uses Tiles by different providers to for a slippymap using JS. The map tiles (aka rasterimages) can be offered via an Tile Map Service (TMS) or an slightly different method (for OSM the numbering here described).
So you can create a list of images you want to get and can transfer them by respeciting legal and tecnical terms. For OSM this is for example:
http://wiki.openstreetmap.org/wiki/Legal_FAQ
https://wiki.openstreetmap.org/wiki/Tile_usage_policy
So you need to create an server/client script, that is able to do such a bulk transfer (maybe as packed archive file?) and ask to place it at a certain place for your user. I'm not experienced enough in Leaflet and can't tell you how to provide them, beside you might add them to the browsers cache itself, or to use a local server to provide them as localhost.
Anyway, if you have more questions, just ask.
So here's what I came up with. I import an area of the map to my database. I then offer this section as a downloadable package. When the user downloads the package, the database is queried and returns all tiles associated with that area in JSON format. The images are stored as blobs. I then pass this array of tiles to a custom leaflet layer which parses the data. Here's the code for the layer:
define([], function() {
L.TileLayer.IDBTiles = L.TileLayer.extend({
initialize: function(url, options, tiles) {
options = L.setOptions(this, options);
// detecting retina displays, adjusting tileSize and zoom levels
if (options.detectRetina && L.Browser.retina && options.maxZoom > 0) {
options.tileSize = Math.floor(options.tileSize / 2);
options.zoomOffset++;
if (options.minZoom > 0) {
options.minZoom--;
}
this.options.maxZoom--;
}
this._url = url;
var subdomains = this.options.subdomains;
if (typeof subdomains === 'string') {
this.options.subdomains = subdomains.split('');
}
this.tiles = tiles;
},
getTileUrl: function (tilePoint) {
this._adjustTilePoint(tilePoint);
var z = this._getZoomForUrl();
var x = tilePoint.x;
var y = tilePoint.y;
var result = this.tiles.filter(function(row) {
return (row.value.tile_column === x
&& row.value.tile_row === y
&& row.value.zoom_level === z);
});
if(result[0]) return result[0].value.tile_data;
else return;
}
});
});
I think you can use a quadtree,i.e. space filling curve. MS Bing Map uses the most simple tile map: http://bcdcspatial.blogspot.de/2012/01/onlineoffline-mapping-map-tiles-and.html?m=1. I think the other maps server also uses a space filling curve, buf it's not so obvious. You may search for ms bings maps quadkey or nick's spatial index hilbert curve. You can also download my php class hilbert curve # phpclasses.org. You can use it with many different space filling curves and to generate a quadkey. A good start is also the hacker's cookbook. There is a whole chapter dedicated to the hilbert curve.

How to set a Custom Icon on clustered Push Pins in Bing Maps?

What I'm trying to do is to change the default icon that is displayed when you set the Clustering Configuration for a Bing Map using the Bing Maps Ajax Control 6.3.
I have a function that loads a Bing Map like this:
function getMap() {
map = new VEMap('map_canvas');
map.SetDashboardSize(VEDashboardSize.Tiny);
var latLong = new VELatLong(21.983801, -101.557617);
map.LoadMap();
var customPin = '<div style="position:relative; left:-10px;top:-20px;"><img src="../Content/images/icons/pin1.png" style="width:40px; height:40px"></div>';
icon.CustomHTML = custom;
var options = new VEClusteringOptions(icon, null);
map.GetShapeLayerByIndex(0).SetClusteringConfiguration(VEClusteringType.Grid, options);
map.SetCenterAndZoom(latLong, 6);
map.SetMouseWheelZoomToCenter(false);
map.EnableShapeDisplayThreshold(true);
map.AttachEvent("onclick", singleMouseHandler);
map.AttachEvent("ondoubleclick", doubleClickMouseHandler);
}
But so far it keeps displaying the same default icon. What am I missing here?
Another thing I was wondering is if there's a way to change the custom icon if a pin in the cluster changes, like if I have 5 green Push Pins but one of them is updated to be a blue Push Pin, is there a way to change the icon that represents that cluster?
I found the reason my approach wasn't working, I keep thinking I'm dealing with classes with constructors that receive parameters, which in this case the VEClusteringOptions class doesn't receive parameters in its constructor. I had to set the Icon property separately:
function getMap() {
map = new VEMap('map_canvas');
map.SetDashboardSize(VEDashboardSize.Tiny);
var latLong = new VELatLong(21.983801, -101.557617);
map.LoadMap();
var customPin = '<div style="position:relative; left:-10px;top:-20px;"><img src="../Content/images/icons/pin1.png" style="width:40px; height:40px"></div>';
icon.CustomHTML = custom;
var options = new VEClusteringOptions();
options.Icon = icon; // here's the "big" difference
map.GetShapeLayerByIndex(0).SetClusteringConfiguration(VEClusteringType.Grid, options);
map.SetCenterAndZoom(latLong, 6);
map.SetMouseWheelZoomToCenter(false);
map.EnableShapeDisplayThreshold(true);
map.AttachEvent("onclick", singleMouseHandler);
map.AttachEvent("ondoubleclick", doubleClickMouseHandler);
}
Now my custom cluster icons are being loaded great, I need to get used to more to the concept of property in the future.
I did the development long time ago for our company site. Did you try the interactive SDK available here?
http://www.bingmapsportal.com/isdk/ajaxv7#Pushpins15
I have added the reference for pushpin development
http://www.microsoft.com/maps/developers/web.aspx

OpenLayers Map BoundingBox calculation

I'm using the GeoServer to hold some maps, and just a simple OpenLayers app to load and show the data (for now).
I'm successfully loading the demo data (which is in WGS84), but when it comes to my data (which is in Balkans Zone 7, EPSG:31277), when I look at the request, it seems like the BBOX is completely out of order.
I checked the BBOX from the GeoServer preview page (which is made with openLayers) and it looks like this, and works:
http://127.0.0.1:2113/geoserver/GISHome/wms?LAYERS=GISHome%3ANis11Katastar&STYLES=&FORMAT=image%2Fjpeg&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG%3A31277&BBOX=7572000,4796000,7574000,4798000&WIDTH=512&HEIGHT=512
The only thing that's different with my request is the BBOX. When copying the BBOX into my request, it works.
http://127.0.0.1:2113/geoserver/wms?LAYERS=Nis11Katastar&FORMAT=image%2Fpng&WIDTH=256&HEIGHT=256&PROJECTION=EPSG%3A31277&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=-180,-90,0,90
In the GeoServer source, the bounds are somehow calculated and hardcoded. The question is, how? Is there a way not to hardcode them? How should I calculate them. I've tried adding bounds, maxExtent, resolution, I'm obviously missing something more than that here. The GeoServer works fine, I'm using the layers from QuantumGIS.
Ext.onReady(function() {
var map = new OpenLayers.Map();
var layer = new OpenLayers.Layer.WMS(
"Global Imagery",
"http://127.0.0.1:2113/geoserver/wms",
{
LAYERS:'Nis11Katastar',
format: 'image/png',
width:600,
height:400,
projection: new OpenLayers.Projection("EPSG:31277"),
}
);
Thankyou.
Oh, yes, I'm using GeoExt, but that doesn't change much.
It seems solved. I was setting the right properties, but to the WMS layer object, not to the map object. As for the bounds question, I'm just copying the bounds from the geoserver control panel.

How do I load a layer transparency and save as a path in the Photoshop JavaScript API?

I'm very new to javascripting and am trying to process a load of layers in photoshop to output each layer's loaded selection as an ai path..
The problem I'm having is understanding the channel arg of selection.load.
In photoshop the drop down of load selection shows the channel name as "layer_7 Transparency". but passing this doesn't seem to work.
for(a=2;a<=AD.layers.length;a++){
AD.layers[a-2].visible = 0;
AD.layers[a-1].visible = 1;
if((checkArray[a-1]!= 1)&&(checkArray[a-1]!= 2)){
var channel = AD.channels.getByName(AD.layers[a-1].name+" Transparency");
AD.selection.load(channel, SelectionType.REPLACE, false);
AD.selection.makeWorkPath(1.0)
newAIFile = new File(tempFolder+"/"+AD.layers[a-1].name+".ai");
AD.exportDocument(newaiFile , ExportType.ILLUSTRATORPATHS , exportOptions)
}
}
In scripting, the first layer in the collection is the one that is added last. It is at index 0 in the Document.artLayers collection.
// Get a reference to the first layer in the document
var layerRef:Layer = app.activeDocument.layers.index(0);
// Get a reference to a layer by name
var baseLayer:Layer = app.activeDocument.artLayers.getByName("Background");
Because layer sets can be nested, you may have to drill down through contained layer sets to reach a particular layer or layer set:
app.activeDocument.layerSets.index(0).layerSets.index(0);
References
Scripting Photoshop: Working with Layers

Categories

Resources