I'm updating an Appcelerator app that used to use "bencoding.map" https://github.com/benbahrenburg/benCoding.Map/blob/master/documentation/index.md.
Now "bencoding.map" is deprecated so I updated to use the native Titanium map feature.
However I now have an issue where the "addKML" from "bencoding.map" is not available in the Titanium map api.
Does anyone know what I can use to replace the KML functionality? The code is below:
function onkmlCompleted(){
Ti.API.info("onkmlCompleted");
Ti.API.info("onkmlCompleted"+JSON.stringify(mapLoadingWindow));
mapLoadingWindow.close({animated:false});
mapView.removeEventListener('kmlCompleted',onkmlCompleted);
};
mapView.addEventListener('kmlCompleted',onkmlCompleted);
mapView.addKML({
path:"some_file.kml", //Path to our kml file
tag : 55, //Integer value used as the tag for all polygons and annotations. If you want use remove you need to set this to a known value.
flyTo:false, //Will set your zoom to show all of your points added (false by default)
//Contains all of the details used to process overlays from your KML file
overlayInfo:{
title:'my kml batch key', //This identifies all of the overlay elements in your kml file. This is also used for delete or query operations.
alpha:0.5, //Alpha value of your overlays
lineWidth:1.2, //Line Width of your overlays
strokeColor:'#000', //Stroke Color of your overlays
color:'yellow', //Sets the color of all your overlays ( if left off, a random color will be selected)
useRandomColor:true, //If true, a random color will be selected, this overrides the color provided if true
}
});
One option would be to convert the kml data to JSON, then add the data to the native Titanium Map via the map module's methods, such as createPolygon, createPolyline, etc., as your data requires.
I've done this using the togeojson Node.js module. Starting with Titanium 6, we can now directly access Node modules from within our projects. Assuming you are using an Alloy project:
cd MyProject/app/assets
npm install togeojson
This will also install some other dependency modules, including xmldom, which we can use as well.
Taking some sample KML LineString data and placing in MyProjects/app/assets, we can then convert it using the togeojson module. This will get us half way there. The Titanium Map module doesn't speak GeoJSON, but since GeoJSON is just JSON, we can iterate through it and get the data we need and then feed it that to the relevant Map module method.
Below is an example of doing all this by sending the KML LineString data to the map's createPolyline method. Assuming this Alloy index.js controller that has a map view with the id of 'map' on it:
//the titanium map module
var Map = require('ti.map');
//the node module we installed
var togeojson = require('togeojson');
//a dependency of togeojson which we will also use
var DOMParser = require('xmldom').DOMParser;
//with out data file in apps/assets
var file = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, "linestring.kml");
var kml = file.read().text;
//the module requires the xml data in XML DOM, so we parse it first
var xml = (new DOMParser()).parseFromString(kml, 'text/xml');
//convert the kml to GeoJSON
var converted = togeojson.kml(xml);
//Here, we iterate through the GeoJSON file and pull out the coordinates to use to
//create our Map polygons, polylines, etc. Your implementation will vary depending
//on the data you are reading
converted.features.forEach(function(feature){
if(feature.geometry.type === 'LineString')
$.map.addPolyline(Map.createPolyline({
points: feature.geometry.coordinates,
strokeColor: '#ff0000',
strokeWidth: '2'
}));
});
$.map.setRegion({
latitude: 37.824664,
latitudeDelta: 0.002,
longitude: -122.364383,
longitudeDelta: 0.002
});
Related
I am using data driven styling to style a Mapbox vector layer for a choropleth map. However, rather than getting the data strictly from the layer properties, I need to use statistic data from a separate object (pulled from our database). This separate object contains one statistic value for each polygon in the vector layer. The object maps the stat values to the vector layer polygons by a variable called "GEOID". In order to marry the polygon with its data, I would like to use a Mapbox expression to get the GEOID value from each polygon in the vector layer and pass this id to a separate function to get the statistic value for the polygon having this GEOID. Is this possible?
vectorLayer: {
id: "fooLayer",
type: "fill",
"source-layer": "foo-layer-dvf1ci",
paint: {
"fill-color": [
"rgba",
100,100,100,
this.getStatForDistrict(["get", "GEOID"])]
]
}
},
getStatForDistrict(districtId) {
console.log("districtId: " + districtId);
let alphaValue = fetchDataForThisDistrictFromDatabase(districtId)
return alphaValue;
},
I see that currently, I am passing ["get", "GEOID"] into the function getStatForDistrict when what I actually need is to pass the computed Mapbox expression.
More on Mapbox-GL's paint property: https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#paint-property
More on Mapbox-GL's expressions syntax: https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions/
No, there is not any way to call arbitrary functions from within expressions, which look up data that doesn't exist within the feature in question.
There are several ways to make choropleths. I'd suggest you start by looking at the mapbox-choropleth library.
Quick version: I’m having trouble displaying a d3 element on a static image displayed by Leaflet. It works if I use d3noob’s (http://bl.ocks.org/d3noob/9211665) example…but I’m having trouble extending it. I’m guessing it’s because of the lang and long translation or the projection but I’m not sure what I need to change. I’m trying to display the geoJSON in the centre of the image (my code on JSFiddle: https://jsfiddle.net/g_at_work/qyhf0qz0/12/)
Longer version:
I'm trying to extend d3noob’s example so that I can display geoJSON on static images using Leaflet and D3 (an requirement from my boss unfortunately). I was able to reproduce d3noob’s tile based example but I've had trouble with the static version.
I've been able to display the static image but I've not been able to display the blue rectangle on the image. I'm not sure what I need to do to manipulate the position of the blue rectangle described in the JSON.
I've tried playing around with setting the coordinates in the projectPoint function but no luck:
function projectPoint(x, y) {
var point = map.latLngToLayerPoint(new L.LatLng(y, x));
this.stream.point(point.x, point.y);
}
At this stage I’m thinking I need to describe a new projection but I’m not sure what.
Here is the code which I’m using to display the static image:
var map = new L.Map("map", {maxZoom:1,center: [0,0], zoom: 3,crs:L.CRS.Simple});
var southWest = map.unproject([0,882],map.getMaxZoom());
var northEast = map.unproject([1085,0],map.getMaxZoom());
var imageBounds = new L.LatLngBounds(southWest,northEast);
L.imageOverlay('http://www.w3schools.com/css/trolltunga.jpg',imageBounds).addTo(map);
map.fitBounds(imageBounds);
It would be great if someone could suggest a strategy for maniuplating the position of the rectangle (I’m new to d3 and leaflet)
Thanks a bunch
G
so after some tinkering I found that creating a new projection enabled me to set the location and scale the map so I could place it where I needed it to be :
var center = d3.geo.centroid(geoShapeInstance);
var scale = [800000];
var offset = [175, 1];
var projection = d3.geo.mercator().scale(scale).center(center).translate(offset);
var path = d3.geo.path().projection(projection);
Fiddling with the 'offset' variable allowed me to set the location and playing with the 'scale' variable allowed me to resize the map (scale is a [x,x] value)
Hope this helps someone.
I am trying to find out if there is a global data array created in D3. I need to be able to access it from anywhere. I have Jquery slider params that I pass to an update function. I will be using the indexes to redraw the chart.Or do I have to create this global myself?
function redraw(first,last) {
var chart = d3.select(".chart");
// this only grabs one rect so I only have one value for _data_
var rect = chart.selectAll("rect");
EDIT: I want the original data so that I can filter it and rerender (See my comment below). But it doenst seen to be in the global space for me to access it.
I developed an script to display 2 layers ob base map.
but it is not zooming properlly.
I am using following code
can you please suggest me
<script type="text/javascript">
var map, layer, select, hover, control;
function init(){
map = new OpenLayers.Map('map', {
controls: [
new OpenLayers.Control.PanZoom(),
new OpenLayers.Control.Permalink(),
new OpenLayers.Control.Navigation()
]
});
layer = new OpenLayers.Layer.WMS(
"States WMS/WFS",
"http://localhost:8080/geoserver/topp/wms",
{layers: 'topp:india_road',transparent: true}
);
select = new OpenLayers.Layer.Vector("Selection", {styleMap:
new OpenLayers.Style(OpenLayers.Feature.Vector.style["select"])
});
hover = new OpenLayers.Layer.Vector("Hover");
map.addLayers([layer, hover, select]);
var wmsLayer = new OpenLayers.Layer.Google('Google Layer',{} );
map.addLayer(wmsLayer);
map.setCenter(new OpenLayers.Bounds(143.83482400000003,-43.648056,148.47914100000003,-39.573891).getCenterLonLat(), 5);
}
</script>
What do you mean by not zooming properly?
Are you finding that they are not matching up with the google maps when zooming in as far as you can go, or the zoom work until you try to pan and then the layers don't stay lined up with google maps? If this is the case then you are probably zooming in further than is supported by the Google map service. There is no easy way to fix this and I recommend you alter allowed scales and zoom with the following settings
minScale - float -- the minimum scale value at which the layer should display
maxScale - float -- the maximum scale value at which the layer should display
numZoomLevels - int -- Total number of zoom levels
Also please see this link on more information about google zoom scales.
If you are finding that none of your layers match the google background. I.E. they look like they are zoomed in out or offset then it is likely that your data is in a different projection to the google maps layer. Google maps uses EPSG:900913 as their SRS. The eisiest way to do this is to let geoserver do the re projection for you. Go to your layer setting in geoserver make sure you have the native projection set correctly and set the declared SRS to EPSG:900913.
If that doesn't help then I think we need more information on exactly what the problem is.
I'd like to create a key to my map that shows the values associated with the different colors, as at the bottom of the drawing:
I can make a series of boxes easily enough. Is there a method somewhere I can input a value to get the color back that the map would use for that value?
First you need a map object. If you have created a map with jvm.WorldMap constructor you have it already, otherwise if you have created a map using jQuery wrapper you can do:
var map = $('#map').vectorMap('get', 'mapObject');
Then to convert the value to color do the following:
var color = map.series.regions[0].scale.getValue(someValue);