Location lat-lng getting wrong when using Yandex Map with flutter_map package - flutter

I am using flutter_map with yandex map like below. When I mark a location, Getting location lat and lon are wrong. So If I draw a polygon on the map, It drawn on wrong location. How to fix this?
FlutterMap(
options: MapOptions(
center: LatLng(41.334554,36.269617),
zoom: 11.0,
maxZoom: 18,
minZoom: 5,
plugins: [
DragMarkerPlugin(),
],
onTap: (value){
print(value.toString());
markLocation(value);
},
),
layers: [
TileLayerOptions(
urlTemplate: 'https://core-sat.maps.yandex.net/tiles?l=sat&v=3.569.0&x={x}&y={y}&z={z}&lang=tr_TR'
),
TileLayerOptions(
urlTemplate: 'http://vec{s}.maps.yandex.net/tiles?l=skl&v=20.06.03&z={z}&x={x}&y={y}&scale=1&lang=tr_TR',
subdomains: ['01', '02', '03', '04'],
backgroundColor: Colors.transparent
),
CircleLayerOptions(
circles: _circles
),
PolygonLayerOptions(
polygons: getPolygons()
),
DragMarkerPluginOptions(
markers: _markers
)
],
mapController: _mapController,
)
Actual position of polygon:
And How to looks on device?

I used custom csr for solve this problem. Thanks to dmitrienkop for his answer.
https://github.com/fleaflet/flutter_map/issues/642
import 'dart:math' as math;
import 'package:flutter_map/plugin_api.dart';
import 'package:latlong/latlong.dart';
class Epsg3395 extends Earth {
#override
final String code = 'EPSG:3395';
#override
final Projection projection = const Mercator();
#override
final Transformation transformation = const Transformation(_scale, 0.5, -_scale, 0.5);
static const num _scale = 0.5 / (math.pi * Mercator.r);
const Epsg3395() : super();
}
class Mercator extends Projection {
static const int r = 6378137;
static const double rMinor = 6356752.314245179;
static final Bounds<double> _bounds = Bounds<double>(
CustomPoint<double>(-20037508.34279, -15496570.73972),
CustomPoint<double>(20037508.34279, 18764656.23138),
);
const Mercator() : super();
#override
Bounds<double> get bounds => _bounds;
#override
CustomPoint project(LatLng latlng) {
var d = math.pi / 180;
var y = latlng.latitude * d;
var tmp = rMinor / r;
var e = math.sqrt(1 - tmp * tmp);
var con = e * math.sin(y);
var ts = math.tan(math.pi / 4 - y / 2) / math.pow((1 - con) / (1 + con), e / 2);
y = -r * math.log(math.max(ts, 1E-10));
return CustomPoint(latlng.longitude * d * r, y);
}
#override
LatLng unproject(CustomPoint point) {
var d = 180 / math.pi;
var tmp = rMinor / r;
var e = math.sqrt(1 - tmp * tmp);
var ts = math.exp(-point.y / r);
var phi = math.pi / 2 - 2 * math.atan(ts);
for (var i = 0, dphi = 0.1, con; i < 15 && dphi.abs() > 1e-7; i++) {
con = e * math.sin(phi);
con = math.pow((1 - con) / (1 + con), e / 2);
dphi = math.pi / 2 - 2 * math.atan(ts * con) - phi;
phi += dphi;
}
return LatLng(phi * d, point.x * d / r);
}
}

Related

Moving Car Animation Using Mapbox in flutter

I've implementing MabBox SDK with one of my flutter app. It has car live tracking screen, which will update car marker position on map based on location received. Here we would like to show car moving animation like this .
I've gone through the MabBox documents, Couldn't find any related document for our use cases. Then I've gone through google's flutter_animarker which doesn't support Mabbox. Anyone please help me on this.
I've finished car moving animation. Here is the final code.
import 'package:flutter/animation.dart';
import 'dart:math' as math;
LatLng? oldLatLng;
bool isCarAnimating = false;
onLocationChange(String latLng) async {
currentLatLng = LatLng(
double.parse(latLng.split(',')[0]), double.parse(latLng.split(',')[1]));
if (cabMarkerSymbol != null && !isCarAnimating)
_animateCabIcon(oldLatLng!, currentLatLng!);
}
_animateCabIcon(LatLng start, LatLng end) async {
try {
AnimationController controller =
AnimationController(vsync: this, duration: Duration(seconds: 3));
Animation animation;
var tween = Tween<double>(begin: 0, end: 1);
animation = tween.animate(controller);
animation.addStatusListener((status) {
if (status == AnimationStatus.completed) {
oldLatLng = end;
isCarAnimating = false;
} else if (status == AnimationStatus.forward) {
isCarAnimating = true;
}
});
controller.forward();
var bearing = getBearing(start, end);
animation.addListener(() async {
var v = animation.value;
var lng = v * end.longitude + (1 - v) * start.longitude;
var lat = v * end.latitude + (1 - v) * start.latitude;
var latLng = LatLng(lat, lng);
var carSymbolOptions = SymbolOptions(
geometry: latLng,
iconRotate: bearing,
);
await _completer.future
.then((map) => map.updateSymbol(carMarkerSymbol!, carSymbolOptions));
});
} catch (e) {
print(e);
}
}
double getBearing(LatLng start, LatLng end) {
var lat1 = start.latitude * math.pi / 180;
var lng1 = start.longitude * math.pi / 180;
var lat2 = end.latitude * math.pi / 180;
var lng2 = end.longitude * math.pi / 180;
var dLon = (lng2 - lng1);
var y = math.sin(dLon) * math.cos(lat2);
var x = math.cos(lat1) * math.sin(lat2) -
math.sin(lat1) * math.cos(lat2) * math.cos(dLon);
var bearing = math.atan2(y, x);
bearing = (bearing * 180) / math.pi;
bearing = (bearing + 360) % 360;
return bearing;
}

How to using flutter implement this html5 canvas animation

I'm learning flutter recently, but I still don't understand the use of flutter canvas,
I hope to get your help, here.
How to using flutter implement this html5 canvas animation?
jsfiddle animation demo link
HTML code
margin: 0;
padding: 0;
background: #000000;
}
canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<canvas id="mycanvas"></canvas>
<script type="text/javascript">
const mycanvas = document.getElementById('mycanvas')
const context = mycanvas.getContext('2d')
const canvasWidth = window.innerWidth
const canvasHeight = window.innerHeight
mycanvas.width = canvasWidth
mycanvas.height = canvasHeight
console.log(canvasWidth, canvasHeight);
// 创建渐变
function createGradient(context, p0, p1) {
const gradient = context.createLinearGradient(p0.x, p0.y, p1.x, p1.y)
gradient.addColorStop(0, 'rgba(255, 255, 0, 0)')
gradient.addColorStop(1, 'rgba(255, 255, 0, 1)')
return gradient
}
// 绘制曲线
function createCurveLine(points) {
const gradient = createGradient(context, points[0], points[points.length - 1])
context.beginPath()
context.moveTo(points[0].x, points[0].y)
// 参数 points 是曲线上一部分连续点的集合,我们用 lineTo 把这些点连结起来,就近似的得到了曲线
for (let i = 0; i < points.length; i++) {
const p = points[i]
context.lineTo(p.x, p.y)
}
context.moveTo(points[0].x, points[0].y)
context.strokeStyle = gradient
context.lineCap = 'round'
context.lineWidth = 5
context.shadowColor = 'rgba(255, 0, 255, 1)'
context.shadowBlur = 10
context.stroke()
}
const P0 = {
x: 100,
y: canvasHeight / 2
}
const P1 = {
x: canvasWidth / 2,
y: canvasHeight / 2 - 200
}
const P2 = {
x: canvasWidth - 100,
y: canvasHeight / 2
}
let t0 = 0
let t1 = 0
let points = [] // 存储曲线上点的集合
const lineLength = 0.3;
function draw() {
context.clearRect(0, 0, canvasWidth, canvasHeight);
if (t1 < lineLength) {
t0 = 0;
}
if (t0 > 1 - lineLength) {
t1 = 1;
}
const currentPoint = {
x: computeCurvePoint(P0.x, P1.x, P2.x, t1),
y: computeCurvePoint(P0.y, P1.y, P2.y, t1)
}
// 每当 t1 变化时,就将对应的点添加到 points 集合中
points.push(currentPoint)
const len = points.length
context.save()
if (len > 1) {
createCurveLine(points.slice(Math.floor(len * t0), Math.max(Math.ceil(len * t1), 2)))
}
context.restore()
t0 += 0.005
t1 += 0.005
if (t0 > 1 && t1 > 1) {
t0 = 0
t1 = 0
points = []
}
requestAnimationFrame(draw)
}
draw()
/*!
* 计算二次贝塞尔曲线上的点
* #param {Number} p0 起始点
* #param {Number} p1 控制点
* #param {Number} p2 结束点
* #param {Number} t 0-1的集合
* #return {Number} 返回计算后的点
*/
function computeCurvePoint(p0, p1, p2, t) {
return (1 - t) * (1 - t) * p0 + 2 * t * (1 - t) * p1 + t * t * p2
}
function arc(...points) {
points.forEach(p => {
context.beginPath()
context.arc(p.x, p.y, 3, 0, Math.PI * 2)
context.stroke();
});
}
</script>
</body>
</html>

Flutter Tensorflowlite Object Detection

I am working on an object recognition application with Flutter.
When the object is detected, it shows on the screen by covering it with container.
I want to convey the title of the detected object to the user audibly. It takes the title from the list named Results and displays it as a map.
I got it to speak the specified texts with TextToSpeech, but I don't know how to do it in real time.
List<Widget> _renderBoxes() {
return widget.results.map((re) {
var _x = re["rect"]["x"];
var _w = re["rect"]["w"];
var _y = re["rect"]["y"];
var _h = re["rect"]["h"];
var scaleW, scaleH, x, y, w, h;
if (widget.screenH / widget.screenW >
widget.previewH / widget.previewW) {
scaleW = widget.screenH / widget.previewH * widget.previewW;
scaleH = widget.screenH;
var difW = (scaleW - widget.screenW) / scaleW;
x = (_x - difW / 2) * scaleW;
w = _w * scaleW;
if (_x < difW / 2) w -= (difW / 2 - _x) * scaleW;
y = _y * scaleH;
h = _h * scaleH;
} else {
scaleH = widget.screenW / widget.previewW * widget.previewH;
scaleW = widget.screenW;
var difH = (scaleH - widget.screenH) / scaleH;
x = _x * scaleW;
w = _w * scaleW;
y = (_y - difH / 2) * scaleH;
h = _h * scaleH;
if (_y < difH / 2) h -= (difH / 2 - _y) * scaleH;
}
return Positioned(
left: math.max(0, x),
top: math.max(0, y),
width: w,
height: h,
child: Container(
padding: const EdgeInsets.only(top: 5.0, left: 5.0),
decoration: BoxDecoration(
border: Border.all(
color: Colors.amber,
width: 1.0,
),
),
child: Text(
"${re["detectedClass"]} ${(re["confidenceInClass"] * 100).toStringAsFixed(0)}%",
style: const TextStyle(
color: Colors.amber,
fontSize: 14.0,
fontWeight: FontWeight.bold,
),
),
),
);
}).toList();
}
The method I tried is
into the build
_res = Map.fromIterable(widget.results, value: (e) => e.detectedClass)
as String;
add _res value
#override
void initState() {
super.initState();
_textToSpeech.speak(_res);
}
I called it inside the method but it gave an error: "type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String' in type cast" and "Each child must be laid out exactly once.
"

Distance calculation Flutter background Location

I am trying to develop a Location service-based Distance calculation app. the problem is I need this to be run when the app is in the background as well. so I used the following plugin to do so.
https://pub.dev/packages/background_location
when this runs on AVD nothing happened but worked fine. but when run on some devices I got the wrong calculations. I have noticed that this happens when the app is in the background this is. following is a partial recreation of mine. I just want to know if my code get any error before posting this as an issue
Future<void> startLocationUpdate() async {
var permission = await Permission.locationAlways.isGranted;
if (!permission) {
var t = await Permission.locationAlways.request();
}
oldPosition2 = Location(
longitude: currentPosition.longitude, latitude: currentPosition.latitude);
isWaited = false;
waitButtonText = "WAIT";
BackgroundLocation.stopLocationService();
BackgroundLocation.setAndroidConfiguration(2000);
await BackgroundLocation.setAndroidNotification(
title: "XXXXXXXXXXXXXXXXX",
message: "XXXXXXXXXXXXXXXXXX",
icon: "XXXXXXXXXXXXXXXXXX",
);
//print('Inside startLocationUpdate');
await BackgroundLocation.startLocationService(distanceFilter: 20);
print('Inside startLocationUpdate 1');
BackgroundLocation.getLocationUpdates((location) {
try {
currentPosition = location;
LatLng pos = LatLng(location.latitude, location.longitude);
var rotation = MapKitHelper.getMarkerRotation(oldPosition2.latitude,
oldPosition2.longitude, pos.latitude, pos.longitude);
Marker movingMaker = Marker(
markerId: MarkerId('moving'),
position: pos,
icon: movingMarkerIcon,
rotation: rotation,
infoWindow: InfoWindow(title: 'Current Location'),
);
setState(() {
CameraPosition cp = new CameraPosition(target: pos, zoom: 17);
rideMapController.animateCamera(CameraUpdate.newCameraPosition(cp));
_markers.removeWhere((marker) => marker.markerId.value == 'moving');
_markers.add(movingMaker);
this.accuracy = location.accuracy.toStringAsFixed(0);
totalSpeed = location.speed;
totalDistance = totalDistance +
CalDistance(oldPosition2 != null ? oldPosition2 : location,
location, DistanceType.Kilometers);
var totalDistanceAdj = totalDistance != 0 ? totalDistance : 1;
//totalFare = 50 + (kmPrice * totalDistanceAdj);
print("distance $totalDistance");
});
oldPosition2 = location;
updateTripDetails(location);
Map locationMap = {
'latitude': location.latitude.toString(),
'longitude': location.longitude.toString(),
};
rideRef = FirebaseDatabase.instance
.reference()
.child("rideRequest/${widget.tripDetails.rideID}");
rideRef.child('driver_location').set(locationMap);
} catch (e) {
FirebaseService.logtoGPSData('Error in updates ${e}');
}
});
}
and the CalDistance method as follows
double CalDistance(Location pos1, Location pos2, DistanceType type) {
print("pos1 : ${pos1.latitude} pos2: ${pos2.latitude}");
double R = (type == DistanceType.Miles) ? 3960 : 6371;
double dLat = this.toRadian(pos2.latitude - pos1.latitude);
double dLon = this.toRadian(pos2.longitude - pos1.longitude);
double a = sin(dLat / 2) * sin(dLat / 2) +
cos(this.toRadian(pos1.latitude)) *
cos(this.toRadian(pos2.latitude)) *
sin(dLon / 2) *
sin(dLon / 2);
double c = 2 * asin(min(1, sqrt(a)));
double d = R * c;
//d = (d*80)/100;
return d;
}
double toRadian(double val) {
return (pi / 180) * val;
}
Any help or hint would be much appreciated

How can one make an ellipse in react-leaflet?

I am trying to draw an ellipse on a map made using react-leaflet, which has built-in support for circles and rectangles.
To achieve this, I am using code to produce an ellipse in (non-react) leaflet from here, that I have adapted and pasted below:
import * as L from 'leaflet';
L.SVG.include ({
_updateEllipse: function (layer) {
var // c = layer._point,
rx = layer._radiusX,
ry = layer._radiusY,
phi = layer._tiltDeg,
endPoint = layer._endPointParams;
var d = 'M' + endPoint.x0 + ',' + endPoint.y0 +
'A' + rx + ',' + ry + ',' + phi + ',' +
endPoint.largeArc + ',' + endPoint.sweep + ',' +
endPoint.x1 + ',' + endPoint.y1 + ' z';
this._setPath(layer, d);
}
});
L.Canvas.include ({
_updateEllipse: function (layer) {
if (layer._empty()) { return; }
var p = layer._point,
ctx = this._ctx,
r = layer._radiusX,
s = (layer._radiusY || r) / r;
this._drawnLayers[layer._leaflet_id] = layer;
ctx.save();
ctx.translate(p.x, p.y);
if (layer._tilt !== 0) {
ctx.rotate( layer._tilt );
}
if (s !== 1) {
ctx.scale(1, s);
}
ctx.beginPath();
ctx.arc(0, 0, r, 0, Math.PI * 2);
ctx.restore();
this._fillStroke(ctx, layer);
},
});
L.Ellipse = L.Path.extend({
options: {
fill: true,
startAngle: 0,
endAngle: 359.9
},
initialize: function (latlng, radii, tilt, options) {
L.setOptions(this, options);
this._latlng = L.latLng(latlng);
if (tilt) {
this._tiltDeg = tilt;
} else {
this._tiltDeg = 0;
}
if (radii) {
this._mRadiusX = radii[0];
this._mRadiusY = radii[1];
}
},
setRadius: function (radii) {
this._mRadiusX = radii[0];
this._mRadiusY = radii[1];
return this.redraw();
},
getRadius: function () {
return new L.point(this._mRadiusX, this._mRadiusY);
},
setTilt: function (tilt) {
this._tiltDeg = tilt;
return this.redraw();
},
getBounds: function () {
// TODO respect tilt (bounds are too big)
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]);
},
// #method setLatLng(latLng: LatLng): this
// Sets the position of a circle marker to a new location.
setLatLng: function (latlng) {
this._latlng = L.latLng(latlng);
this.redraw();
return this.fire('move', {latlng: this._latlng});
},
// #method getLatLng(): LatLng
// Returns the current geographical position of the circle marker
getLatLng: function () {
return this._latlng;
},
setStyle: L.Path.prototype.setStyle,
_project: function () {
var lngRadius = this._getLngRadius(),
latRadius = this._getLatRadius(),
latlng = this._latlng,
pointLeft = this._map.latLngToLayerPoint([latlng.lat, latlng.lng - lngRadius]),
pointBelow = this._map.latLngToLayerPoint([latlng.lat - latRadius, latlng.lng]);
this._point = this._map.latLngToLayerPoint(latlng);
this._radiusX = Math.max(this._point.x - pointLeft.x, 1);
this._radiusY = Math.max(pointBelow.y - this._point.y, 1);
this._tilt = Math.PI * this._tiltDeg / 180;
this._endPointParams = this._centerPointToEndPoint();
this._updateBounds();
},
_updateBounds: function () {
// http://math.stackexchange.com/questions/91132/how-to-get-the-limits-of-rotated-ellipse
var sin = Math.sin(this._tilt);
var cos = Math.cos(this._tilt);
var sinSquare = sin * sin;
var cosSquare = cos * cos;
var aSquare = this._radiusX * this._radiusX;
var bSquare = this._radiusY * this._radiusY;
var halfWidth = Math.sqrt(aSquare*cosSquare+bSquare*sinSquare);
var halfHeight = Math.sqrt(aSquare*sinSquare+bSquare*cosSquare);
var w = this._clickTolerance();
var p = [halfWidth + w, halfHeight + w];
this._pxBounds = new L.Bounds(this._point.subtract(p), this._point.add(p));
},
_update: function () {
if (this._map) {
this._updatePath();
}
},
_updatePath: function () {
this._renderer._updateEllipse(this);
},
_getLatRadius: function () {
return (this._mRadiusY / 40075017) * 360;
},
_getLngRadius: function () {
return ((this._mRadiusX / 40075017) * 360) / Math.cos((Math.PI / 180) * this._latlng.lat);
},
_centerPointToEndPoint: function () {
// Convert between center point parameterization of an ellipse
// too SVG's end-point and sweep parameters. This is an
// adaptation of the perl code found here:
// http://commons.oreilly.com/wiki/index.php/SVG_Essentials/Paths
var c = this._point,
rx = this._radiusX,
ry = this._radiusY,
theta2 = (this.options.startAngle + this.options.endAngle) * (Math.PI / 180),
theta1 = this.options.startAngle * (Math.PI / 180),
delta = this.options.endAngle,
phi = this._tiltDeg * (Math.PI / 180);
// Determine start and end-point coordinates
var x0 = c.x + Math.cos(phi) * rx * Math.cos(theta1) +
Math.sin(-phi) * ry * Math.sin(theta1);
var y0 = c.y + Math.sin(phi) * rx * Math.cos(theta1) +
Math.cos(phi) * ry * Math.sin(theta1);
var x1 = c.x + Math.cos(phi) * rx * Math.cos(theta2) +
Math.sin(-phi) * ry * Math.sin(theta2);
var y1 = c.y + Math.sin(phi) * rx * Math.cos(theta2) +
Math.cos(phi) * ry * Math.sin(theta2);
var largeArc = (delta > 180) ? 1 : 0;
var sweep = (delta > 0) ? 1 : 0;
return {'x0': x0, 'y0': y0, 'tilt': phi, 'largeArc': largeArc,
'sweep': sweep, 'x1': x1, 'y1': y1};
},
_empty: function () {
return this._radiusX && this._radiusY && !this._renderer._bounds.intersects(this._pxBounds);
},
_containsPoint : function (p) {
// http://stackoverflow.com/questions/7946187/point-and-ellipse-rotated-position-test-algorithm
var sin = Math.sin(this._tilt);
var cos = Math.cos(this._tilt);
var dx = p.x - this._point.x;
var dy = p.y - this._point.y;
var sumA = cos * dx + sin * dy;
var sumB = sin * dx - cos * dy;
return sumA * sumA / (this._radiusX * this._radiusX) + sumB * sumB / (this._radiusY * this._radiusY) <= 1;
}
});
export const lellipse = function (latlng, radii, tilt, options) {
return new L.Ellipse(latlng, radii, tilt, options);
};
To create an ellipse to use with react-leaflet, I followed the example of Circle in react-leaflet to produce the following Ellipse component:
import PropTypes from 'prop-types'
import { lellipse as LeafletEllipse } from '../l.ellipse';
import Path from './Path'
import children from './propTypes/children'
import latlng from './propTypes/latlng'
import type { LatLng, MapLayerProps, PathOptions } from './types'
type LeafletElement = LeafletEllipse
type Props = {
center: LatLng,
mSemiMajorAxis: number,
mSemiMinorAxis: number,
degreeTiltFromWest: number,
} & MapLayerProps &
PathOptions &
Object
export default class Ellipse extends Path<LeafletElement, Props> {
static propTypes = {
center: latlng.isRequired,
mSemiMajorAxis: PropTypes.number.isRequired,
mSemiMinorAxis: PropTypes.number.isRequired,
degreeTiltFromWest: PropTypes.number.isRequired,
children: children,
}
createLeafletElement(props: Props): LeafletElement {
const { center, mSemiMajorAxis, mSemiMinorAxis, degreeTiltFromWest, ...options } = props
return new LeafletEllipse(center, [mSemiMajorAxis, mSemiMinorAxis], this.getOptions(options))
}
updateLeafletElement(fromProps: Props, toProps: Props) {
if (toProps.center !== fromProps.center) {
this.leafletElement.setLatLng(toProps.center);
}
if (toProps.degreeTiltFromWest !== fromProps.degreeTiltFromWest) {
this.leafletElement.setTilt(toProps.degreeTiltFromWest);
}
if (toProps.mSemiMinorAxis !== fromProps.mSemiMinorAxis || toProps.mSemiMajorAxis !== fromProps.mSemiMajorAxis) {
this.leafletElement.setRadius([toProps.mSemiMajorAxis, toProps.mSemiMinorAxis]);
}
}
}
The problem with the code is that it does not render an ellipse and it does not throw any errors. Could someone suggest how to render an ellipse with react-leaflet? Thanks.
Your createLeafletElement function is missing the tilt parameter. It should be:
createLeafletElement(props) {
const { center, mSemiMajorAxis, mSemiMinorAxis, degreeTiltFromWest, ...options } = props
return new LeafletEllipse(center, [mSemiMajorAxis, mSemiMinorAxis], degreeTiltFromWest, this.getOptions(options))
}
See below for the complete file (in ES6 rather than in typescript, as I find it clearer).
import React, { PropTypes } from 'react';
import { lellipse as LeafletEllipse } from './l.ellipse';
import { Path, withLeaflet } from 'react-leaflet';
class Ellipse extends Path {
static propTypes = {
center: PropTypes.arrayOf(PropTypes.number).isRequired,
mSemiMajorAxis: PropTypes.number.isRequired,
mSemiMinorAxis: PropTypes.number.isRequired,
degreeTiltFromWest: PropTypes.number.isRequired
}
createLeafletElement(props) {
const { center, mSemiMajorAxis, mSemiMinorAxis, degreeTiltFromWest, ...options } = props
return new LeafletEllipse(center, [mSemiMajorAxis, mSemiMinorAxis], degreeTiltFromWest, this.getOptions(options))
}
updateLeafletElement(fromProps, toProps) {
if (toProps.center !== fromProps.center) {
this.leafletElement.setLatLng(toProps.center);
}
if (toProps.degreeTiltFromWest !== fromProps.degreeTiltFromWest) {
this.leafletElement.setTilt(toProps.degreeTiltFromWest);
}
if (toProps.mSemiMinorAxis !== fromProps.mSemiMinorAxis || toProps.mSemiMajorAxis !== fromProps.mSemiMajorAxis) {
this.leafletElement.setRadius([toProps.mSemiMajorAxis, toProps.mSemiMinorAxis]);
}
}
}
export default class withLeaflet(Ellipse);