How to transform a GWT OpenLayers VectorFeature? - gwt

I am using OpenLayers GWT. I want to put an GeoJSON shape on top of a Google Maps layer. I have done as follows:
String gson = "{here I put a valid GeoJSON string}";
GeoJSON geoJSON = new GeoJSON();
VectorFeature[] vf = geoJSON.read(gson);
myShapeLayer.addFeature(vf[0]);
The shape is showing on the map, but not a the right position. I think I have to transform the Vector to EPSG:900913 but I don't know how to do that with the VectorFeature. There is no transform function to use.
How can I apply the transformation to a GWT VectorFeature?
This question is not getting responses. I would like to explain better what I want to know:
In javascript Openlayers you can do:
var projWGS84 = new OpenLayers.Projection("EPSG:4326");
var proj900913 = new OpenLayers.Projection("EPSG:900913");
feature.geometry.transform(projWGS84, proj900913);
How can I do the same in the GWT version of OpenLayers?
Thanks in advance.

OpenLayers-GWT is missing the GeoJSON constructor that will take an options parameter, this has to be added in the OpenLayers-GWT source. In the mean time this has been added to the KML Vector class. So now you can do like this:
String kmlString = "{<string with KML>}";
FormatOptions formatOptions = new FormatOptions();
formatOptions.setInternalProjection(new Projection("EPSG:900913"));
formatOptions.setExternalProjection(new Projection("EPSG:4326"));
KML kml = new KML(formatOptions);
VectorFeature[] vf = KML.read(kmlString);
myShapeLayer.addFeature(vf[0]);
In the same way it should be added to the GeoJSON class to make the tranformation work.

Related

How to implement mapbox SDK v10 to android app written in Java?

I am trying to implement Mapbox SDK v10 in my android app that's completely written in Java.
I have been able to show the map and even the camera points to my current location but when I am trying to put a marker on the map I can't find the relevant codes in java because only kotlin codes are present
// Create an instance of the Annotation API and get the PointAnnotationManager. val annotationApi = mapView?.annotations val pointAnnotationManager = annotationApi?.createPointAnnotationManager(mapView) // Set options for the resulting symbol layer. val pointAnnotationOptions: PointAnnotationOptions = PointAnnotationOptions() // Define a geographic coordinate. .withPoint(Point.fromLngLat(18.06, 59.31)) // Specify the bitmap you assigned to the point annotation // The bitmap will be added to map style automatically. .withIconImage(YOUR_ICON_BITMAP) // Add the resulting pointAnnotation to the map. pointAnnotationManager?.create(pointAnnotationOptions)
So I have 2 questions-
1)How can I put an annotation or marker on the map using java?
2)On the other hand I have been able to use Mapbox SDK v9 successfully ,but it's marked as legacy so can I still use this SDK in my app or there can be some problem in the future if I use SDK v9?
These are the codes for adding a marker, polyline of polygon in mapbox10 java:
private void AddMarker(Point point)
{
AnnotationPlugin annotationApi = AnnotationPluginImplKt.getAnnotations(mapView);
CircleAnnotationManager circleAnnotationManager = CircleAnnotationManagerKt.createCircleAnnotationManager(annotationApi, new AnnotationConfig());
CircleAnnotationOptions circleAnnotationOptions = new CircleAnnotationOptions()
.withPoint(point)
.withCircleRadius(7.0)
.withCircleColor("#ee4e8b")
.withCircleStrokeWidth(1.0)
.withDraggable(true)
.withCircleStrokeColor("#ffffff");
circleAnnotationManager.create(circleAnnotationOptions);
}
private void DrawPolyLine() {
AnnotationPlugin annotationApi = AnnotationPluginImplKt.getAnnotations(mapView);
PolylineAnnotationManager polylineAnnotationManager = PolylineAnnotationManagerKt.createPolylineAnnotationManager(annotationApi,new AnnotationConfig());
PolylineAnnotationOptions polylineAnnotationOptions = new PolylineAnnotationOptions()
.withPoints(pointList)
.withLineColor("#ee4e8b")
.withLineWidth(4);
polylineAnnotationManager.create(polylineAnnotationOptions);
}
private void DrawPolygon(List<Point> myPointList) {
List<Point> pointList = myPointList;
pointList.add(myPointList.get(0));
List<List<Point>> polygonList = new ArrayList<>();
polygonList.add(pointList);
polygonAnnotationManager = PolygonAnnotationManagerKt.createPolygonAnnotationManager(annotationApi,new AnnotationConfig());
PolygonAnnotationOptions polygonAnnotationOptions = new PolygonAnnotationOptions()
.withPoints(polygonList)
.withFillColor("#ee4e8b")
.withFillOpacity(0.5);
PolygonAnnotation polygonAnnotation = polygonAnnotationManager.create(polygonAnnotationOptions);
}
remember for marker annotation we have to types: Point annotation and Circle annotation but their implementation of them are the same.

Leaflet how to show map scale inline with attribution text?

I want to show the scale of my leaflet map using L.control.scale() however I want to position the scale the same way as the Google Maps API offers. I need the scale to be inline with map attribution. I have attached an image below.
Google Maps API (how i want it)
Leaflet (how it currently is)
I am using the following code to create the scale and add it to my map.
L.control.scale().addTo(map);
To simply put the scale in the same corner of the map as the attribution, you can just set the position option when you create the scale control:
L.control.scale({position:'bottomright', metric: false}).addTo(map);
To make the scale actually go inline with the attribution, you can create a custom control that includes both the scale widget and the attribution text. Leaflet is designed to be extensible, so you can extend the source code for L.Control.Scale to just add what you need:
L.Control.AttrScale = L.Control.Scale.extend({
onAdd: function (map) {
var className = 'leaflet-control-scale',
wrapper = L.DomUtil.create('div', 'leaflet-control-attr-scale'),
attribution = L.DomUtil.create('div', 'leaflet-control-attribution', wrapper),
container = L.DomUtil.create('div', className, wrapper),
options = this.options;
wrapper.style.display = "flex";
wrapper.style.alignItems = "center";
attribution.innerHTML = "My attribution string";
this._addScales(options, className + '-line', container);
map.on(options.updateWhenIdle ? 'moveend' : 'move', this._update, this);
map.whenReady(this._update, this);
return wrapper;
},
});
map.addControl(new L.Control.AttrScale({position:'bottomright', metric: false}))
The example above shows a static attribution string before the scale. You can still use the normal options to position the control and set whether to show the metric and/or imperial scale. You will probably also want to create the map with the attributionControl: false option, to avoid the default attribution showing.
If you need to dynamically set the attribution message based on the map selection (like the normal attribution control does), look at the source code for L.Control.Attribution to see what extra functionality you need to incorporate into the custom control.

Get leaflet marker from a layer

I'm new to leaflet and am trying to implement a set of markers with different CSS-styles.
So, I am aware that after adding a marker to a map I can access different CSS-attributes by calling getElement() on my marker for example:
marker.addTo(map);
marker.getElement().style.borderColor = '#000';
This works just fine, but when adding a marker to a layer, this can no longer be used since a TypeError occurs (getElement() is undefined). Here is the example code where the error occurs:
myLayer.addLayer(marker);
marker.getElement().style.borderColor = '#000';
Am I overlooking a simpler way to set CSS-Attributes for markers and divicons that are added to layers or is there a similar way to access layer-added markers and divicons in JavaScript?
So I found a solution that is working for me.
The idea is to extend the function that is used to create the icon.
Last answer here github.com/Leaflet/Leaflet/issues/5231 helped a lot.
var borderSize = ...;
L.DivIcon.Custom = L.DivIcon.extend({
createIcon: function(oldIcon) {
var icon = L.DivIcon.prototype.createIcon.call(this, oldIcon);
icon.style.borderSize = borderSize;
...
return icon;
}
})
var icon = new L.DivIcon.Custom({
...
});
var ll = L.latLng(entry.Longitude, entry.Latitude);
var marker = L.marker(ll, {
icon: icon
})
this.myLayer.addLayer(marker);
Welcome to SO!
When not added onto a map (since your parent myLayer may not be added to the map itself), a marker does not have any element.
If you do not need to change too many styles individually and dynamically, you might rather use the className option of your Icon / DivIcon.

How to extract GeoJSON/WKT from drawn layer in Leaflet?

I would like to extract coordinates in GeoJSON/WKT format from user drawn polygon. I found next code:
drawnItems = new L.FeatureGroup();
drawnItems.addLayer(layer);
myjson = drawnItems.toGeoJSON();
console.log(myjson)
But in console I see only Object {__ob__: Observer} like this
I used example from here
What I am doing wrong?
If you were expecting to get a string, then you just missed the JSON.stringify(myjson) on the next line of the example you refer to.

Unable to add marker to Angular Leaflet directive

I'm trying to add a marker to the Leaflet directive but somehow it doesn't accept markers created with the default L.marker() method.
The directive is used as follows:
<leaflet markers="markers" center="center" layers="layers" defaults="defaults"></leaflet>
I'm extending my $scope in the controller as prescribed:
angular.extend($scope, {
markers: {},
//markers: { { someName: {lat:52.163815,lng:5.365131} } //this does work
});
Adding a marker afterwards doesn't work somehow. First the .markers object is not an array, so I can't just add any elements using push(). But even adding an element as associative array doesn't work:
var marker = L.marker(L.latLng(52.163815, 5.365131));
$scope.markers[0] = marker;
The error is:
[AngularJS - Leaflet] The marker definition is not valid.
[AngularJS - Leaflet] Received invalid data on the marker 0.
I'm overlooking something very simple but I've got no idea what... Any lead would be greatly appreciated.
$scope.markers is expecting to get an object with marker properties, not the marker itself. What would work in your example is just a LatLng object, before wrapping it as Marker.
$scope.markers[0] = L.latLng(52.163815, 5.365131);
Or, if you get Markers from the outside, you can get it back from the inside:
$scope.markers[0] = marker.getLatLng();
Obviously, that doesn't convey another markers' properties, just coordinates.