// Adds a circle to the map and holds a refference on this point public void AddCircle(double radius, Color color) { float r = (float)radius / OnlineMapsUtils.tileSize; float step = 360f / segments; double x, y; _Pin.GetPosition(out x, out y); OnlineMapsProjection projection = OnlineMaps.instance.projection; projection.CoordinatesToTile(x, y, OnlineMaps.instance.zoom, out x, out y); points = new List <Vector2>(); for (int i = 0; i < segments; i++) { points.Add(new Vector2()); double px = x + Mathf.Cos(step * i * Mathf.Deg2Rad) * r; double py = y + Mathf.Sin(step * i * Mathf.Deg2Rad) * r; projection.TileToCoordinates(px, py, OnlineMaps.instance.zoom, out px, out py); points[i] = new Vector2((float)px, (float)py); } _Circle = new OnlineMapsDrawingPoly(points, color, 3); OnlineMaps.instance.AddDrawingElement(_Circle); _Acting = false; }
private static void Init() { _rootCluster = new Cluster(1); map = OnlineMaps.instance; projection = map.projection; map.OnChangePosition += OnChangePosition; map.OnChangeZoom += OnChangeZoom; inited = true; }
private double Angle(Vector2 userCoordinares, Vector2 markerCoordinates) { int zoom = 15; int maxX = 1 << (zoom - 1); double userTileX, userTileY, markerTileX, markerTileY; OnlineMapsProjection projection = MapManager.Instance.map.projection; projection.CoordinatesToTile(userCoordinares.x, userCoordinares.y, zoom, out userTileX, out userTileY); projection.CoordinatesToTile(markerCoordinates.x, markerCoordinates.y, zoom, out markerTileX, out markerTileY); // Calculate the angle between locations. double angle = OnlineMapsUtils.Angle2D(userTileX, userTileY, markerTileX, markerTileY); return(angle); }
public override bool HitTest(Vector2 positionLngLat, int zoom) { if (points == null) { return(false); } double cx, cy; OnlineMapsProjection projection = api.projection; projection.CoordinatesToTile(positionLngLat.x, positionLngLat.y, zoom, out cx, out cy); int valueType = -1; // 0 - Vector2, 1 - float, 2 - double, 3 - OnlineMapsVector2d object v1 = null; object v2 = null; object v3 = null; int i = 0; float w = hitTestWidth.HasValue ? hitTestWidth.Value : width; float sqrW = w * w; foreach (object p in points) { if (valueType == -1) { if (p is Vector2) { valueType = 0; } else if (p is float) { valueType = 1; } else if (p is double) { valueType = 2; } else if (p is OnlineMapsVector2d) { valueType = 3; } } object v4 = v3; v3 = v2; v2 = v1; v1 = p; double p1tx = 0, p1ty = 0, p2tx = 0, p2ty = 0; bool drawPart = false; if (valueType == 0) { if (i > 0) { Vector2 p1 = (Vector2)v2; Vector2 p2 = (Vector2)v1; projection.CoordinatesToTile(p1.x, p1.y, zoom, out p1tx, out p1ty); projection.CoordinatesToTile(p2.x, p2.y, zoom, out p2tx, out p2ty); drawPart = true; } } else if (valueType == 3) { if (i > 0) { OnlineMapsVector2d p1 = (OnlineMapsVector2d)v2; OnlineMapsVector2d p2 = (OnlineMapsVector2d)v1; projection.CoordinatesToTile(p1.x, p1.y, zoom, out p1tx, out p1ty); projection.CoordinatesToTile(p2.x, p2.y, zoom, out p2tx, out p2ty); drawPart = true; } } else if (i > 2 && i % 2 == 1) { if (valueType == 1) { projection.CoordinatesToTile((float)v4, (float)v3, zoom, out p1tx, out p1ty); projection.CoordinatesToTile((float)v2, (float)v1, zoom, out p2tx, out p2ty); } else if (valueType == 2) { projection.CoordinatesToTile((double)v4, (double)v3, zoom, out p1tx, out p1ty); projection.CoordinatesToTile((double)v2, (double)v1, zoom, out p2tx, out p2ty); } drawPart = true; } if (drawPart) { double nx, ny; OnlineMapsUtils.NearestPointStrict(cx, cy, p1tx, p1ty, p2tx, p2ty, out nx, out ny); double dx = (cx - nx) * OnlineMapsUtils.tileSize; double dy = (cy - ny) * OnlineMapsUtils.tileSize; double d = dx * dx + dy * dy; if (d < sqrW) { return(true); } } i++; } return(false); }
private OnlineMapsProvider(string id, string title) { this.id = id.ToLower(); this.title = title; projection = new OnlineMapsProjectionSphericalMercator(); }
protected List <Vector2> GetLocalPoints(IEnumerable points, bool closed = false, bool optimize = true) { double sx, sy; int zoom = map.zoom; float zoomCoof = map.zoomCoof; OnlineMapsProjection projection = map.projection; projection.CoordinatesToTile(tlx, tly, zoom, out sx, out sy); int max = 1 << zoom; int halfMax = max / 2; if (localPoints == null) { localPoints = new List <Vector2>(); } else { localPoints.Clear(); } double ppx = 0; double scaleX = OnlineMapsUtils.tileSize * OnlineMapsControlBaseDynamicMesh.instance.sizeInScene.x / map.buffer.renderState.width / zoomCoof; double scaleY = OnlineMapsUtils.tileSize * OnlineMapsControlBaseDynamicMesh.instance.sizeInScene.y / map.buffer.renderState.height / zoomCoof; double prx = 0, pry = 0; object v1 = null; int i = -1; int valueType = -1; // 0 - Vector2, 1 - float, 2 - double, 3 - OnlineMapsVector2d bool isOptimized = false; double px = 0, py = 0; IEnumerator enumerator = points.GetEnumerator(); while (enumerator.MoveNext()) { i++; object p = enumerator.Current; if (valueType == -1) { if (p is Vector2) { valueType = 0; } else if (p is float) { valueType = 1; } else if (p is double) { valueType = 2; } else if (p is OnlineMapsVector2d) { valueType = 3; } } object v2 = v1; v1 = p; bool useValue = false; if (valueType == 0) { Vector2 point = (Vector2)p; projection.CoordinatesToTile(point.x, point.y, zoom, out px, out py); useValue = true; } else if (valueType == 3) { OnlineMapsVector2d point = (OnlineMapsVector2d)p; projection.CoordinatesToTile(point.x, point.y, zoom, out px, out py); useValue = true; } else if (i % 2 == 1) { if (valueType == 1) { projection.CoordinatesToTile((float)v2, (float)v1, zoom, out px, out py); } else if (valueType == 2) { projection.CoordinatesToTile((double)v2, (double)v1, zoom, out px, out py); } useValue = true; } if (!useValue) { continue; } isOptimized = false; if (optimize && i > 0) { if ((prx - px) * (prx - px) + (pry - py) * (pry - py) < 0.001) { isOptimized = true; continue; } } prx = px; pry = py; px -= sx; py -= sy; if (i == 0) { double ox = px - map.width / OnlineMapsUtils.tileSize / 2; if (ox < -halfMax) { px += max; } else if (ox > halfMax) { px -= max; } } else { double ox = px - ppx; int maxIt = 3; while (maxIt-- > 0) { if (ox < -halfMax) { px += max; ox += max; } else if (ox > halfMax) { px -= max; ox -= max; } else { break; } } } ppx = px; double rx1 = px * scaleX; double ry1 = py * scaleY; Vector2 np = new Vector2((float)rx1, (float)ry1); localPoints.Add(np); } if (isOptimized) { px -= sx; py -= sy; if (i == 0) { double ox = px - map.width / OnlineMapsUtils.tileSize / 2; if (ox < -halfMax) { px += max; } else if (ox > halfMax) { px -= max; } } else { double ox = px - ppx; int maxIt = 3; while (maxIt-- > 0) { if (ox < -halfMax) { px += max; ox += max; } else if (ox > halfMax) { px -= max; ox -= max; } else { break; } } } double rx1 = px * scaleX; double ry1 = py * scaleY; Vector2 np = new Vector2((float)rx1, (float)ry1); localPoints.Add(np); } if (closed) { localPoints.Add(localPoints[0]); } return(localPoints); }
protected List <Vector2> GetLocalPoints(IEnumerable points, bool closed = false, bool optimize = true) { double sx, sy; OnlineMaps map = api; int apiZoom = map.buffer.apiZoom; OnlineMapsProjection projection = map.projection; projection.CoordinatesToTile(tlx, tly, apiZoom, out sx, out sy); int maxX = 1 << apiZoom; if (localPoints == null) { localPoints = new List <Vector2>(); } else { localPoints.Clear(); } double ppx = 0; double scaleX = OnlineMapsUtils.tileSize * map.tilesetSize.x / map.tilesetWidth; double scaleY = OnlineMapsUtils.tileSize * map.tilesetSize.y / map.tilesetHeight; double prx = 0, pry = 0; object v1 = null; int i = -1; int valueType = -1; // 0 - Vector2, 1 - float, 2 - double, 3 - OnlineMapsVector2d bool isOptimized = false; double px = 0, py = 0; IEnumerator enumerator = points.GetEnumerator(); while (enumerator.MoveNext()) { i++; object p = enumerator.Current; if (valueType == -1) { if (p is Vector2) { valueType = 0; } else if (p is float) { valueType = 1; } else if (p is double) { valueType = 2; } else if (p is OnlineMapsVector2d) { valueType = 3; } } object v2 = v1; v1 = p; bool useValue = false; if (valueType == 0) { Vector2 point = (Vector2)p; projection.CoordinatesToTile(point.x, point.y, apiZoom, out px, out py); useValue = true; } else if (valueType == 3) { OnlineMapsVector2d point = (OnlineMapsVector2d)p; projection.CoordinatesToTile(point.x, point.y, apiZoom, out px, out py); useValue = true; } else if (i % 2 == 1) { if (valueType == 1) { projection.CoordinatesToTile((float)v2, (float)v1, apiZoom, out px, out py); } else if (valueType == 2) { projection.CoordinatesToTile((double)v2, (double)v1, apiZoom, out px, out py); } useValue = true; } if (!useValue) { continue; } isOptimized = false; if (optimize && i > 0) { if ((prx - px) * (prx - px) + (pry - py) * (pry - py) < 0.001) { isOptimized = true; continue; } } prx = px; pry = py; px -= sx; py -= sy; if (i == 0) { if (px < maxX * -0.25) { px += maxX; } else if (px > maxX * 0.75) { px -= maxX; } } else { double gpx = px + maxX; double lpx = px - maxX; if (Math.Abs(ppx - gpx) < Math.Abs(ppx - px)) { px = gpx; } else if (Math.Abs(ppx - lpx) < Math.Abs(ppx - px)) { px = lpx; } } ppx = px; double rx1 = px * scaleX; double ry1 = py * scaleY; Vector2 np = new Vector2((float)rx1, (float)ry1); localPoints.Add(np); } if (isOptimized) { px -= sx; py -= sy; if (i == 0) { if (px < maxX * -0.25) { px += maxX; } else if (px > maxX * 0.75) { px -= maxX; } } else { double gpx = px + maxX; double lpx = px - maxX; if (Math.Abs(ppx - gpx) < Math.Abs(ppx - px)) { px = gpx; } else if (Math.Abs(ppx - lpx) < Math.Abs(ppx - px)) { px = lpx; } } double rx1 = px * scaleX; double ry1 = py * scaleY; Vector2 np = new Vector2((float)rx1, (float)ry1); localPoints.Add(np); } if (closed) { localPoints.Add(localPoints[0]); } return(localPoints); }
protected List <Vector2> GetLocalPoints(IEnumerable points, bool closed = false, bool optimize = true) { double sx, sy; int apiZoom = api.buffer.apiZoom; OnlineMapsProjection projection = api.projection; projection.CoordinatesToTile(tlx, tly, apiZoom, out sx, out sy); int maxX = 1 << api.zoom; //int off = closed ? 1 : 0; //int pointsCount = points.Count; //int maxI = pointsCount + off; List <Vector2> localPoints = new List <Vector2>(1024); double ppx = 0; double scaleX = OnlineMapsUtils.tileSize * api.tilesetSize.x / api.tilesetWidth; double scaleY = OnlineMapsUtils.tileSize * api.tilesetSize.y / api.tilesetHeight; double prx = 0, pry = 0; object v1 = null, v2 = null; int i = 0; int valueType = -1; // 0 - Vector2, 1 - float, 2 - double bool isOptimized = false; double px = 0, py = 0; foreach (object p in points) { if (valueType == -1) { if (p is Vector2) { valueType = 0; } else if (p is float) { valueType = 1; } else if (p is double) { valueType = 2; } } v2 = v1; v1 = p; bool useValue = false; if (valueType == 0) { Vector2 point = (Vector2)p; projection.CoordinatesToTile(point.x, point.y, apiZoom, out px, out py); useValue = true; } else if (i % 2 == 1) { if (valueType == 1) { projection.CoordinatesToTile((float)v2, (float)v1, apiZoom, out px, out py); } else if (valueType == 2) { projection.CoordinatesToTile((double)v2, (double)v1, apiZoom, out px, out py); } useValue = true; } i++; if (!useValue) { continue; } isOptimized = false; if (optimize && i > 0) { if ((prx - px) * (prx - px) + (pry - py) * (pry - py) < 0.001) { isOptimized = true; continue; } } prx = px; pry = py; px -= sx; py -= sy; if (i == 0) { if (px < maxX * -0.25) { px += maxX; } else if (px > maxX * 0.75) { px -= maxX; } } else { double gpx = px + maxX; double lpx = px - maxX; if (Math.Abs(ppx - gpx) < Math.Abs(ppx - px)) { px = gpx; } else if (Math.Abs(ppx - lpx) < Math.Abs(ppx - px)) { px = lpx; } } ppx = px; double rx1 = px * scaleX; double ry1 = py * scaleY; Vector2 np = new Vector2((float)rx1, (float)ry1); localPoints.Add(np); } if (isOptimized) { px -= sx; py -= sy; if (i == 0) { if (px < maxX * -0.25) { px += maxX; } else if (px > maxX * 0.75) { px -= maxX; } } else { double gpx = px + maxX; double lpx = px - maxX; if (Math.Abs(ppx - gpx) < Math.Abs(ppx - px)) { px = gpx; } else if (Math.Abs(ppx - lpx) < Math.Abs(ppx - px)) { px = lpx; } } double rx1 = px * scaleX; double ry1 = py * scaleY; Vector2 np = new Vector2((float)rx1, (float)ry1); localPoints.Add(np); } if (closed) { localPoints.Add(localPoints[0]); } /*for (int i = 0; i < maxI; i++) * { * int ci = i; * if (ci >= pointsCount) ci -= pointsCount; * double px, py; * * Vector2 point = points[ci]; * projection.CoordinatesToTile(point.x, point.y, apiZoom, out px, out py); * * if (optimize && i > 0 && i < maxI - 1) * { * if ((prx - px) * (prx - px) + (pry - py) * (pry - py) < 0.001) continue; * } * * prx = px; * pry = py; * * px -= sx; * py -= sy; * * if (i == 0) * { * if (px < maxX * -0.25) px += maxX; * else if (px > maxX * 0.75) px -= maxX; * } * else * { * double gpx = px + maxX; * double lpx = px - maxX; * * if (Math.Abs(ppx - gpx) < Math.Abs(ppx - px)) px = gpx; * else if (Math.Abs(ppx - lpx) < Math.Abs(ppx - px)) px = lpx; * } * * ppx = px; * * double rx1 = px * scaleX; * double ry1 = py * scaleY; * * Vector2 np = new Vector2((float)rx1, (float)ry1); * localPoints.Add(np); * if (localPoints.Count == localPoints.Capacity) localPoints.Capacity += 1024; * }*/ return(localPoints); }
protected List <Vector2> GetLocalPoints(List <Vector2> points, bool closed = false, bool optimize = true) { double sx, sy; int apiZoom = api.buffer.apiZoom; OnlineMapsProjection projection = api.projection; projection.CoordinatesToTile(tlx, tly, apiZoom, out sx, out sy); int maxX = 1 << api.zoom; int off = closed ? 1 : 0; int pointsCount = points.Count; int maxI = pointsCount + off; List <Vector2> localPoints = new List <Vector2>(Mathf.Min(maxI, 1024)); double ppx = 0; double scaleX = OnlineMapsUtils.tileSize * api.tilesetSize.x / api.tilesetWidth; double scaleY = OnlineMapsUtils.tileSize * api.tilesetSize.y / api.tilesetHeight; double prx = 0, pry = 0; for (int i = 0; i < maxI; i++) { int ci = i; if (ci >= pointsCount) { ci -= pointsCount; } double px, py; Vector2 point = points[ci]; projection.CoordinatesToTile(point.x, point.y, apiZoom, out px, out py); if (optimize && i > 0 && i < maxI - 1) { if ((prx - px) * (prx - px) + (pry - py) * (pry - py) < 0.001) { continue; } } prx = px; pry = py; px -= sx; py -= sy; if (i == 0) { if (px < maxX * -0.25) { px += maxX; } else if (px > maxX * 0.75) { px -= maxX; } } else { double gpx = px + maxX; double lpx = px - maxX; if (Math.Abs(ppx - gpx) < Math.Abs(ppx - px)) { px = gpx; } else if (Math.Abs(ppx - lpx) < Math.Abs(ppx - px)) { px = lpx; } } ppx = px; double rx1 = px * scaleX; double ry1 = py * scaleY; Vector2 np = new Vector2((float)rx1, (float)ry1); localPoints.Add(np); if (localPoints.Count == localPoints.Capacity) { localPoints.Capacity += 1024; } } return(localPoints); }
private void GroupMarkers() { OnlineMapsProjection projection = OnlineMaps.instance.projection; List <MarkerGroup> groups = new List <MarkerGroup>(); for (int zoom = 20; zoom >= 3; zoom--) { List <OnlineMapsMarker> ms = markers.Select(m => m).ToList(); for (int j = 0; j < ms.Count - 1; j++) { OnlineMapsMarker marker = ms[j]; MarkerGroup group = null; double mx, my; marker.GetPosition(out mx, out my); double px, py; projection.CoordinatesToTile(mx, my, zoom, out px, out py); int k = j + 1; while (k < ms.Count) { OnlineMapsMarker marker2 = ms[k]; double m2x, m2y; marker2.GetPosition(out m2x, out m2y); double p2x, p2y; projection.CoordinatesToTile(m2x, m2y, zoom, out p2x, out p2y); if (OnlineMapsUtils.Magnitude(px, py, p2x, p2y) < distance) { if (group == null) { group = new MarkerGroup(zoom, groupTexture); groups.Add(group); group.Add(marker); if (marker.range.min == 3) { marker.range.min = zoom + 1; } } group.Add(marker2); if (marker2.range.min == 3) { marker2.range.min = zoom + 1; } ms.RemoveAt(k); px = group.tilePositionX; py = group.tilePositionY; } else { k++; } } } } foreach (MarkerGroup g in groups) { g.Apply(font); } }
/// <summary> /// Get the center point and best zoom for the array of coordinates. /// </summary> /// <param name="positions">Array of coordinates</param> /// <param name="center">Center coordinate</param> /// <param name="zoom">Best zoom</param> public static void GetCenterPointAndZoom(Vector2[] positions, out Vector2 center, out int zoom) { OnlineMaps api = OnlineMaps.instance; OnlineMapsProjection projection = api.projection; float minX = Single.MaxValue; float minY = Single.MaxValue; float maxX = Single.MinValue; float maxY = Single.MinValue; foreach (Vector2 p in positions) { if (p.x < minX) { minX = p.x; } if (p.y < minY) { minY = p.y; } if (p.x > maxX) { maxX = p.x; } if (p.y > maxY) { maxY = p.y; } } float rx = maxX - minX; float ry = maxY - minY; center = new Vector2(rx / 2 + minX, ry / 2 + minY); int width = api.width; int height = api.height; float countX = width / (float)tileSize / 2; float countY = height / (float)tileSize / 2; for (int z = 20; z > 4; z--) { bool success = true; double cx, cy; projection.CoordinatesToTile(center.x, center.y, z, out cx, out cy); foreach (Vector2 pos in positions) { double px, py; projection.CoordinatesToTile(pos.x, pos.y, z, out px, out py); px -= cx - countX; py -= cy - countY; if (px < 0 || py < 0 || px > width || py > height) { success = false; break; } } if (success) { zoom = z; return; } } zoom = 3; }
/// <summary> /// Get the center point and best zoom for the array of markers. /// </summary> /// <param name="markers">Array of markers.</param> /// <param name="center">Center point.</param> /// <param name="zoom">Best zoom.</param> public static void GetCenterPointAndZoom(OnlineMapsMarkerBase[] markers, out Vector2 center, out int zoom) { OnlineMaps api = OnlineMaps.instance; OnlineMapsProjection projection = api.projection; double minX = Double.MaxValue; double minY = Double.MaxValue; double maxX = Double.MinValue; double maxY = Double.MinValue; foreach (OnlineMapsMarkerBase marker in markers) { double mx, my; marker.GetPosition(out mx, out my); if (mx < minX) { minX = mx; } if (my < minY) { minY = my; } if (mx > maxX) { maxX = mx; } if (my > maxY) { maxY = my; } } double rx = maxX - minX; double ry = maxY - minY; center = new Vector2((float)(rx / 2 + minX), (float)(ry / 2 + minY)); int width = api.width; int height = api.height; float countX = width / (float)tileSize / 2; float countY = height / (float)tileSize / 2; bool useZoomMin = false; for (int z = 20; z > 4; z--) { bool success = true; double bx, by; projection.CoordinatesToTile(center.x, center.y, z, out bx, out by); foreach (OnlineMapsMarkerBase marker in markers) { double mx, my; marker.GetPosition(out mx, out my); double px, py; projection.CoordinatesToTile(mx, my, z, out px, out py); px -= bx - countX; py -= by - countY; if (marker is OnlineMapsMarker) { useZoomMin = true; OnlineMapsMarker m = marker as OnlineMapsMarker; OnlineMapsVector2i ip = m.GetAlignedPosition(new OnlineMapsVector2i((int)(px * tileSize), (int)(py * tileSize))); if (ip.x < 0 || ip.y < 0 || ip.x + m.width > width || ip.y + m.height > height) { success = false; break; } } else if (marker is OnlineMapsMarker3D) { if (px < 0 || py < 0 || px > width || py > height) { success = false; break; } } else { throw new Exception("Wrong marker type"); } } if (success) { zoom = z; if (useZoomMin) { zoom -= 1; } return; } } zoom = 3; }