/// <summary> /// Gets aligned offset (in pixels). /// </summary> /// <returns>Aligned offset.</returns> public OnlineMapsVector2i GetAlignOffset() { OnlineMapsVector2i offset = new OnlineMapsVector2i(); if (align == OnlineMapsAlign.BottomRight || align == OnlineMapsAlign.Right || align == OnlineMapsAlign.TopRight) { offset.x = _textureWidth; } else if (align == OnlineMapsAlign.Bottom || align == OnlineMapsAlign.Center || align == OnlineMapsAlign.Top) { offset.x = _textureWidth / 2; } if (align == OnlineMapsAlign.BottomRight || align == OnlineMapsAlign.Bottom || align == OnlineMapsAlign.BottomLeft) { offset.y = _textureHeight; } else if (align == OnlineMapsAlign.Left || align == OnlineMapsAlign.Center || align == OnlineMapsAlign.Right) { offset.y = _textureHeight / 2; } return(offset); }
private void InitTiles(int zoom, OnlineMapsBufferZoom activeZoom, int countX, OnlineMapsVector2i pos, int countY, int maxY, List <OnlineMapsTile> newBaseTiles) { //IEnumerable<OnlineMapsTile> tiles = OnlineMapsTile.tiles.Where(t => t.provider == api.provider && t.zoom == activeZoom.id && t.type == api.type); IEnumerable <OnlineMapsTile> tiles = activeZoom.tiles; int maxX = 1 << bufferZoom; for (int x = 0; x < countX; x++) { int px = x + pos.x; if (px < 0) { px += maxX; } else if (px >= maxX) { px -= maxX; } for (int y = 0; y < countY; y++) { InitTile(zoom, activeZoom, pos, maxY, newBaseTiles, y, tiles, px); } } }
private void UpdateBuildings() { if (!zoomRange.InRange(api.zoom)) { RemoveAllBuildings(); return; } double tlx, tly, brx, bry; api.GetTopLeftPosition(out tlx, out tly); api.GetBottomRightPosition(out brx, out bry); api.projection.CoordinatesToTile(tlx, tly, api.zoom, out tlx, out tly); api.projection.CoordinatesToTile(brx, bry, api.zoom, out brx, out bry); OnlineMapsVector2i newTopLeft = new OnlineMapsVector2i((int)Math.Round(tlx - 2), (int)Math.Round(tly - 2)); OnlineMapsVector2i newBottomRight = new OnlineMapsVector2i((int)Math.Round(brx + 2), (int)Math.Round(bry + 2)); if (newTopLeft != topLeft || newBottomRight != bottomRight) { topLeft = newTopLeft; bottomRight = newBottomRight; LoadNewBuildings(); } if (lastRequestTime + requestRate < Time.time) { SendRequest(); } UpdateBuildingsPosition(); }
private void Draw() { if (control.markerManager == null) { return; } float s = OnlineMapsUtils.tileSize; OnlineMapsVector2i bufferPosition = map.buffer.bufferPosition; OnlineMapsVector2i frontBufferPosition = map.buffer.frontBufferPosition; int bufferZoom = map.buffer.renderState.zoom; double sx, sy, ex, ey; map.projection.TileToCoordinates(bufferPosition.x + frontBufferPosition.x / s, bufferPosition.y + frontBufferPosition.y / s, bufferZoom, out sx, out sy); map.projection.TileToCoordinates(bufferPosition.x + (frontBufferPosition.x + map.buffer.renderState.width) / s, bufferPosition.y + (frontBufferPosition.y + map.height) / s, bufferZoom, out ex, out ey); if (ex < sx) { ex += 360; } IEnumerable <OnlineMapsMarker> usedMarkers = control.markerManager.Where(m => m.enabled && m.range.InRange(bufferZoom)); usedMarkers = OnSortMarker != null?OnSortMarker(usedMarkers) : usedMarkers.OrderByDescending(m => m, new MarkerComparer()); foreach (OnlineMapsMarker marker in usedMarkers) { SetMarkerToBuffer(marker, bufferPosition, bufferZoom, frontBufferPosition, sx, sy, ex, ey); } }
private void GetFrontBufferPosition() { double px, py; // Tile of center position map.projection.CoordinatesToTile(renderState.longitude, renderState.latitude, renderState.zoom, out px, out py); int countX = renderState.width / OnlineMapsUtils.tileSize; int countY = renderState.height / OnlineMapsUtils.tileSize; // Tile center position in the backbuffer px -= bufferPosition.x; py -= bufferPosition.y; // Top-left frontbuffer tile in the backbuffer px -= countX / 2f * renderState.zoomCoof; py -= countY / 2f * renderState.zoomCoof; // Top-left frontbuffer pixel in the backbuffer int ix = (int)(px * OnlineMapsUtils.tileSize); int iy = (int)(py * OnlineMapsUtils.tileSize); if (iy < 0) { iy = 0; } else if (iy >= (int)(height - renderState.height * renderState.zoomCoof)) { iy = (int)(height - renderState.height * renderState.zoomCoof); } frontBufferPosition = new OnlineMapsVector2i(ix, iy); }
/// <summary> /// Determines if the marker at the specified coordinates. /// </summary> /// <param name="positionLatLng"> /// Position. /// </param> /// <param name="zoom"> /// The zoom. /// </param> /// <returns> /// True if the marker in position, false if not. /// </returns> public bool HitTest(Vector2 positionLatLng, int zoom) { if (OnlineMapsControlBase.instance is OnlineMapsTileSetControl) { OnlineMapsVector2i pos = OnlineMapsUtils.LatLongToTilef(position, zoom) * OnlineMapsUtils.tileSize; float w = width * scale; float h = height * scale; pos = GetAlignedPosition(pos); Vector2 mPos = OnlineMapsUtils.LatLongToTilef(positionLatLng, zoom) * OnlineMapsUtils.tileSize; return(mPos.x >= pos.x + w * (markerColliderRect.x + 0.5f) && mPos.x <= pos.x + w * (markerColliderRect.xMax + 0.5f) && mPos.y >= pos.y + w * (markerColliderRect.y + 0.5f) && mPos.y <= pos.y + h * (markerColliderRect.yMax + 0.5f)); } else { OnlineMapsVector2i pos = OnlineMapsUtils.LatLongToTilef(position, zoom) * OnlineMapsUtils.tileSize; int w = width; int h = height; pos = GetAlignedPosition(pos); Vector2 mPos = OnlineMapsUtils.LatLongToTilef(positionLatLng, zoom) * OnlineMapsUtils.tileSize; return(mPos.x >= pos.x + w * (markerColliderRect.x + 0.5f) && mPos.x <= pos.x + w * (markerColliderRect.xMax + 0.5f) && mPos.y >= pos.y + w * (markerColliderRect.y + 0.5f) && mPos.y <= pos.y + h * (markerColliderRect.yMax + 0.5f)); } }
private void InitTile(int zoom, OnlineMapsVector2i pos, int maxY, List <OnlineMapsTile> newBaseTiles, int y, int px) { int py = y + pos.y; if (py < 0 || py >= maxY) { return; } OnlineMapsTile tile; if (!OnlineMapsTile.GetTile(zoom, px, py, out tile)) { OnlineMapsTile parent = null; if (!api.useCurrentZoomTiles) { int ptx = px / 2; int pty = py / 2; if (OnlineMapsTile.GetTile(zoom - 1, ptx, pty, out parent)) { parent.used = true; } } tile = new OnlineMapsTile(px, py, zoom, api, parent) { OnSetColor = OnTileSetColor }; } newBaseTiles.Add(tile); tile.used = true; }
public override void Draw(Color32[] buffer, OnlineMapsVector2i bufferPosition, int bufferWidth, int bufferHeight, int zoom, bool invertY = false) { if (!visible) { return; } DrawLineToBuffer(buffer, bufferPosition, bufferWidth, bufferHeight, zoom, points, color, width, false, invertY); }
public override bool Equals(object obj) { OnlineMapsVector2i v = obj as OnlineMapsVector2i; if (v == null) { return(false); } return(this == v); }
public override void Draw(Color32[] buffer, OnlineMapsVector2i bufferPosition, int bufferWidth, int bufferHeight, int zoom, bool invertY = false) { if (!visible) { return; } FillPoly(buffer, bufferPosition, bufferWidth, bufferHeight, zoom, points, backgroundColor, invertY); DrawLineToBuffer(buffer, bufferPosition, bufferWidth, bufferHeight, zoom, points, borderColor, borderWidth, true, invertY); }
private Rect GetMarkerRect(OnlineMapsMarker marker) { const int s = OnlineMapsUtils.tileSize; Vector2 p = OnlineMapsUtils.LatLongToTilef(marker.position, bufferZoom); p.x -= bufferPosition.x; p.y -= bufferPosition.y; OnlineMapsVector2i ip = marker.GetAlignedPosition(new OnlineMapsVector2i((int)(p.x * s), (int)(p.y * s))); return(new Rect(ip.x, ip.y, marker.width, marker.height)); }
private void InitTile(int zoom, OnlineMapsBufferZoom activeZoom, OnlineMapsVector2i pos, int maxY, List <OnlineMapsTile> newBaseTiles, int y, IEnumerable <OnlineMapsTile> ts, int px) { int py = y + pos.y; if (py < 0 || py >= maxY) { return; } OnlineMapsTile tile = null; foreach (OnlineMapsTile t in ts) { if (t.x == px && t.y == py) { tile = t; break; } } if (tile == null) { OnlineMapsTile parent = null; if (!api.useCurrentZoomTiles && zooms.ContainsKey(zoom - 1)) { int ptx = px / 2; int pty = py / 2; foreach (OnlineMapsTile t in zooms[zoom - 1].tiles) { if (t.x == ptx && t.y == pty) { parent = t; parent.used = true; break; } } } tile = new OnlineMapsTile(px, py, zoom, api, parent) { OnSetColor = OnTileSetColor }; activeZoom.tiles.Add(tile); } newBaseTiles.Add(tile); tile.used = true; if (api.target == OnlineMapsTarget.texture) { SetBufferTile(tile); } }
private void OnDisable() { RemoveAllBuildings(); if (osmRequest != null) { osmRequest.OnComplete = null; osmRequest = null; } sendBuildingsReceived = false; topLeft = OnlineMapsVector2i.zero; bottomRight = OnlineMapsVector2i.zero; }
public override void UpdateControl() { base.UpdateControl(); if (sizeInScene != lastSizeInScene) { ReinitMapMesh(); lastSizeInScene = sizeInScene; } _bufferPosition = null; }
private void UpdateMesh() { _bufferPosition = null; _alpha = alpha; int w1 = api.tilesetWidth / OnlineMapsUtils.tileSize; int h1 = api.tilesetHeight / OnlineMapsUtils.tileSize; int subMeshVX = 1; int subMeshVZ = 1; Vector2 subMeshSize = new Vector2(api.tilesetSize.x / w1, api.tilesetSize.y / h1); Vector2 topLeftPosition = api.topLeftPosition; Vector2 bottomRightPosition = api.bottomRightPosition; Vector2 tlPos = OnlineMapsUtils.LatLongToTilef(topLeftPosition, api.zoom); Vector2 pos = tlPos - bufferPosition; int maxX = (2 << api.zoom) / 2; if (pos.x >= maxX) { pos.x -= maxX; } Vector3 startPos = new Vector3(subMeshSize.x * pos.x, 0, -subMeshSize.y * pos.y); int w = w1 + 2; int h = h1 + 2; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { UpdateMapSubMesh(x, y, w, h, subMeshSize, subMeshVX, subMeshVZ, startPos, 0, topLeftPosition, bottomRightPosition); } } overlayMesh.vertices = vertices; overlayMesh.uv = uv; for (int i = 0; i < overlayMesh.subMeshCount; i++) { overlayMesh.SetTriangles(overlayMesh.GetTriangles(i), i); } overlayMesh.RecalculateBounds(); }
private Rect GetMarkerRect(OnlineMapsMarker marker) { const int s = OnlineMapsUtils.tileSize; double tx, ty; marker.GetTilePosition(out tx, out ty); tx -= bufferPosition.x; ty -= bufferPosition.y; OnlineMapsVector2i ip = marker.GetAlignedPosition((int)(tx * s), (int)(ty * s)); return(new Rect(ip.x, ip.y, marker.width, marker.height)); }
private OnlineMapsVector2i GetBackBufferPosition(double px, double py, OnlineMapsVector2i _bufferPosition, int zoom, int apiWidth, int apiHeight) { api.projection.CoordinatesToTile(px, py, zoom, out px, out py); int countX = apiWidth / OnlineMapsUtils.tileSize + 2; int countY = apiHeight / OnlineMapsUtils.tileSize + 2; px -= countX / 2f + _bufferPosition.x - 1; py -= countY / 2f + _bufferPosition.y - 1; int ix = (int)(px / countX * width); int iy = (int)(py / countY * height); return(new OnlineMapsVector2i(ix, iy)); }
protected void DrawLineToBuffer(Color32[] buffer, OnlineMapsVector2i bufferPosition, int bufferWidth, int bufferHeight, int zoom, List <Vector2> points, Color32 color, float weight, bool closed, bool invertY) { if (color.a == 0) { return; } double sx, sy; api.projection.CoordinatesToTile(tlx, tly, zoom, out sx, out sy); int maxX = 1 << zoom; int off = closed ? 1 : 0; int w = Mathf.RoundToInt(weight); double ppx1 = 0; int bx1 = bufferPosition.x; int bx2 = bx1 + bufferWidth / OnlineMapsUtils.tileSize; int by1 = bufferPosition.y; int by2 = by1 + bufferHeight / OnlineMapsUtils.tileSize; int count = points.Count; for (int j = 0; j < count + off - 1; j++) { Vector2 p1 = points[j]; Vector2 p2 = points[j + 1 >= count ? j - count + 1 : j + 1]; double p1tx, p1ty, p2tx, p2ty; api.projection.CoordinatesToTile(p1.x, p1.y, zoom, out p1tx, out p1ty); api.projection.CoordinatesToTile(p2.x, p2.y, zoom, out p2tx, out p2ty); if ((p1tx < bx1 && p2tx < bx1) || (p1tx > bx2 && p2tx > bx2)) { continue; } if ((p1ty < by1 && p2ty < by1) || (p1ty > by2 && p2ty > by2)) { continue; } DrawLinePartToBuffer(buffer, bufferPosition, bufferWidth, bufferHeight, color, sx, sy, p1tx, p1ty, p2tx, p2ty, j, maxX, ref ppx1, w, invertY); } }
private Rect GetMarkerRect(OnlineMapsMarker marker) { const int s = OnlineMapsUtils.tileSize; double mx, my; marker.GetPosition(out mx, out my); double tx, ty; api.projection.CoordinatesToTile(mx, my, bufferZoom, out tx, out ty); tx -= bufferPosition.x; ty -= bufferPosition.y; OnlineMapsVector2i ip = marker.GetAlignedPosition(new OnlineMapsVector2i((int)(tx * s), (int)(ty * s))); return(new Rect(ip.x, ip.y, marker.width, marker.height)); }
private void GetFrontBufferPosition(double px, double py, OnlineMapsVector2i _bufferPosition, int zoom, int apiWidth, int apiHeight) { OnlineMapsVector2i pos = GetBackBufferPosition(px, py, _bufferPosition, zoom, apiWidth, apiHeight); int ix = pos.x; int iy = pos.y; if (iy < 0) { iy = 0; } else if (iy >= height - apiHeight) { iy = height - apiHeight; } frontBufferPosition = new OnlineMapsVector2i(ix, iy); }
private void UpdateBuildings() { if (!zoomRange.InRange(map.floatZoom)) { RemoveAllBuildings(); return; } if (Math.Abs(heightScale - _heightScale) > float.Epsilon || lastSizeInScene != OnlineMapsControlBaseDynamicMesh.instance.sizeInScene) { needUpdateScale = true; } double tlx, tly, brx, bry; map.GetTileCorners(out tlx, out tly, out brx, out bry); OnlineMapsVector2i newTopLeft = new OnlineMapsVector2i((int)Math.Round(tlx - 2), (int)Math.Round(tly - 2)); OnlineMapsVector2i newBottomRight = new OnlineMapsVector2i((int)Math.Round(brx + 2), (int)Math.Round(bry + 2)); if (newTopLeft != topLeft || newBottomRight != bottomRight) { topLeft = newTopLeft; bottomRight = newBottomRight; RequestNewBuildings(); } if (lastRequestTime + requestRate < Time.time) { SendRequest(); } if (needUpdateScale) { UpdateBuildingsScale(); } else if (needUpdatePosition) { UpdateBuildingsPosition(); } needUpdatePosition = false; needUpdateScale = false; }
private void SetColorToBuffer(Color clr, OnlineMapsVector2i ip, int y, int x) { if (clr.a == 0) { return; } int bufferIndex = (ip.y + y) * width + ip.x + x; if (clr.a < 1) { float alpha = clr.a; Color bufferColor = backBuffer[bufferIndex]; clr.a = 1; clr.r = Mathf.Lerp(bufferColor.r, clr.r, alpha); clr.g = Mathf.Lerp(bufferColor.g, clr.g, alpha); clr.b = Mathf.Lerp(bufferColor.b, clr.b, alpha); } backBuffer[bufferIndex] = clr; }
public void SetColorToBuffer(Color clr, OnlineMapsVector2i ip, int y, int x) { if (Math.Abs(clr.a) < float.Epsilon) { return; } int bufferIndex = (renderState.height - ip.y - y) * renderState.width + ip.x + x; if (clr.a < 1) { float alpha = clr.a; Color bufferColor = frontBuffer[bufferIndex]; clr.a = 1; clr.r = Mathf.Lerp(bufferColor.r, clr.r, alpha); clr.g = Mathf.Lerp(bufferColor.g, clr.g, alpha); clr.b = Mathf.Lerp(bufferColor.b, clr.b, alpha); } frontBuffer[bufferIndex] = clr; }
private void OnDisable() { RemoveAllBuildings(); if (osmRequest != null) { osmRequest.OnComplete = null; osmRequest = null; } sendBuildingsReceived = false; topLeft = OnlineMapsVector2i.zero; bottomRight = OnlineMapsVector2i.zero; if (map != null) { map.OnChangePosition -= OnMapPositionChanged; map.OnChangeZoom -= OnMapZoomChanged; map.OnLateUpdateAfter -= OnUpdate; } }
private void UpdateBuildings() { if (!zoomRange.InRange(api.zoom)) { RemoveAllBuildings(); return; } OnlineMapsVector2i newTopLeft = OnlineMapsUtils.LatLongToTile(api.topLeftPosition, api.zoom) - new OnlineMapsVector2i(1, 1); OnlineMapsVector2i newBottomRight = OnlineMapsUtils.LatLongToTile(api.bottomRightPosition, api.zoom) + new OnlineMapsVector2i(1, 1); if (newTopLeft != topLeft || newBottomRight != bottomRight) { topLeft = newTopLeft; bottomRight = newBottomRight; LoadNewBuildings(); } UpdateBuildingsPosition(); }
/// <summary> /// Gets aligned position. /// </summary> /// <param name="pos"> /// Buffer position. /// </param> /// <returns> /// The aligned buffer position. /// </returns> public OnlineMapsVector2i GetAlignedPosition(OnlineMapsVector2i pos) { OnlineMapsVector2i offset = GetAlignOffset(); if (_rotation == 0) { return(pos - offset); } float angle = 1 - Mathf.Repeat(_rotation * 360, 360); Matrix4x4 matrix = new Matrix4x4(); matrix.SetTRS(new Vector3(_width / 2, 0, _height / 2), Quaternion.Euler(0, angle, 0), Vector3.one); Vector3 off = matrix.MultiplyPoint(new Vector3(offset.x - _textureWidth / 2, 0, offset.y - _textureHeight / 2)); pos.x -= (int)off.x; pos.y -= (int)off.z; return(pos); }
private void UpdateBuildings(bool updatePosition) { if (!zoomRange.InRange(map.zoom)) { RemoveAllBuildings(); return; } double tlx, tly, brx, bry; map.GetTileCorners(out tlx, out tly, out brx, out bry); OnlineMapsVector2i newTopLeft = new OnlineMapsVector2i((int)Math.Round(tlx - 2), (int)Math.Round(tly - 2)); OnlineMapsVector2i newBottomRight = new OnlineMapsVector2i((int)Math.Round(brx + 2), (int)Math.Round(bry + 2)); if (newTopLeft != topLeft || newBottomRight != bottomRight) { topLeft = newTopLeft; bottomRight = newBottomRight; RequestNewBuildings(); } if (lastRequestTime + requestRate < Time.time) { SendRequest(); } if (updatePosition || Math.Abs(prevUpdateTLX - tlx) > double.Epsilon || Math.Abs(prevUpdateTLY - tly) > double.Epsilon || Math.Abs(prevUpdateBRX - brx) > double.Epsilon || Math.Abs(prevUpdateBRY - bry) > double.Epsilon) { prevUpdateTLX = tlx; prevUpdateTLY = tly; prevUpdateBRX = brx; prevUpdateBRY = bry; UpdateBuildingsPosition(); } }
private void InitTiles(int zoom, int countX, OnlineMapsVector2i pos, int countY, int maxY, List <OnlineMapsTile> newBaseTiles) { int maxX = 1 << bufferZoom; for (int x = 0; x < countX; x++) { int px = x + pos.x; if (px < 0) { px += maxX; } else if (px >= maxX) { px -= maxX; } for (int y = 0; y < countY; y++) { InitTile(zoom, pos, maxY, newBaseTiles, y, px); } } }
private void UpdateBuildings() { if (!zoomRange.InRange(map.floatZoom)) { RemoveAllBuildings(); return; } double tlx, tly, brx, bry; map.GetTileCorners(out tlx, out tly, out brx, out bry); OnlineMapsVector2i newTopLeft = new OnlineMapsVector2i((int)Math.Round(tlx - 2), (int)Math.Round(tly - 2)); OnlineMapsVector2i newBottomRight = new OnlineMapsVector2i((int)Math.Round(brx + 2), (int)Math.Round(bry + 2)); if (newTopLeft != topLeft || newBottomRight != bottomRight) { topLeft = newTopLeft; bottomRight = newBottomRight; RequestNewBuildings(); } if (lastRequestTime + requestRate < Time.time) { SendRequest(); } if (needUpdateScale) { UpdateBuildingsScale(); } else if (needUpdatePosition) { UpdateBuildingsPosition(); } needUpdatePosition = false; needUpdateScale = false; }
private void GetFrontBufferPosition(double px, double py, OnlineMapsVector2i _bufferPosition, float zoom, int mapWidth, int mapHeight) { int izoom = (int)zoom; // Tile of center position map.projection.CoordinatesToTile(px, py, izoom, out px, out py); int countX = width / OnlineMapsUtils.tileSize; int countY = height / OnlineMapsUtils.tileSize; float zoomScale1 = 1 - (zoom - izoom) / 4; // Tile center position in the backbuffer px -= _bufferPosition.x - 1; py -= _bufferPosition.y - 1; // Top-left frontbuffer tile in the backbuffer px -= countX / 2f * zoomScale1; py -= countY / 2f * zoomScale1; // Top-left frontbuffer pixel in the backbuffer int ix = (int)(px / countX * width); int iy = (int)(py / countY * height); float zoomScale = 1 - (zoom - izoom) / 2; if (iy < 0) { iy = 0; } else if (iy >= (int)(height - mapHeight * zoomScale)) { iy = (int)(height - mapHeight * zoomScale); } frontBufferPosition = new OnlineMapsVector2i(ix, iy); }
/// <summary> /// Draw element on the map. /// </summary> /// <param name="buffer">Backbuffer</param> /// <param name="bufferPosition">Backbuffer position</param> /// <param name="bufferWidth">Backbuffer width</param> /// <param name="bufferHeight">Backbuffer height</param> /// <param name="zoom">Zoom of the map</param> public virtual void Draw(Color[] buffer, OnlineMapsVector2i bufferPosition, int bufferWidth, int bufferHeight, int zoom) { }
public override void Draw(Color[] buffer, OnlineMapsVector2i bufferPosition, int bufferWidth, int bufferHeight, int zoom) { DrawLineToBuffer(buffer, bufferPosition, bufferWidth, bufferHeight, zoom, points, color, weight, false); }
/// <summary> /// Gets aligned position. /// </summary> /// <param name="pos"> /// Buffer position. /// </param> /// <returns> /// The aligned buffer position. /// </returns> public OnlineMapsVector2i GetAlignedPosition(OnlineMapsVector2i pos) { OnlineMapsVector2i offset = GetAlignOffset(); if (_rotation == 0) return pos - offset; float angle = 1 - Mathf.Repeat(_rotation * 360, 360); Matrix4x4 matrix = new Matrix4x4(); matrix.SetTRS(new Vector3(_width / 2, 0, _height / 2), Quaternion.Euler(0, angle, 0), Vector3.one); Vector3 off = matrix.MultiplyPoint(new Vector3(offset.x - _textureWidth / 2, 0, offset.y - _textureHeight / 2)); pos.x -= (int)off.x; pos.y -= (int)off.z; return pos; }
private void SetColorToBuffer(Color clr, OnlineMapsVector2i ip, int y, int x) { if (clr.a == 0) return; int bufferIndex = (ip.y + y) * width + ip.x + x; if (clr.a < 1) { float alpha = clr.a; Color bufferColor = backBuffer[bufferIndex]; clr.a = 1; clr.r = Mathf.Lerp(bufferColor.r, clr.r, alpha); clr.g = Mathf.Lerp(bufferColor.g, clr.g, alpha); clr.b = Mathf.Lerp(bufferColor.b, clr.b, alpha); } backBuffer[bufferIndex] = clr; }
private void InitTile(int zoom, OnlineMapsBufferZoom activeZoom, OnlineMapsVector2i pos, int maxY, List<OnlineMapsTile> newBaseTiles, int y, IEnumerable<OnlineMapsTile> ts, int px) { int py = y + pos.y; if (py < 0 || py >= maxY) return; OnlineMapsTile tile = null; foreach (OnlineMapsTile t in ts) { if (t.x == px && t.y == py) { tile = t; break; } } if (tile == null) { OnlineMapsTile parent = null; if (!api.useCurrentZoomTiles && zooms.ContainsKey(zoom - 1)) { int ptx = px / 2; int pty = py / 2; foreach (OnlineMapsTile t in zooms[zoom - 1].tiles) { if (t.x == ptx && t.y == pty) { parent = t; parent.used = true; break; } } } tile = new OnlineMapsTile(px, py, zoom, api, parent) { OnSetColor = OnTileSetColor }; activeZoom.tiles.Add(tile); } newBaseTiles.Add(tile); tile.used = true; if (api.target == OnlineMapsTarget.texture) SetBufferTile(tile); }
private OnlineMapsVector2i GetBackBufferPosition(double px, double py, OnlineMapsVector2i _bufferPosition, int zoom, int apiWidth, int apiHeight) { OnlineMapsUtils.LatLongToTiled(px, py, zoom, out px, out py); int countX = apiWidth / OnlineMapsUtils.tileSize + 2; int countY = apiHeight / OnlineMapsUtils.tileSize + 2; px -= countX / 2f + _bufferPosition.x - 1; py -= countY / 2f + _bufferPosition.y - 1; int ix = (int) ((px / countX) * width); int iy = (int) ((py / countY) * height); return new OnlineMapsVector2i(ix, iy); }
protected void FillPoly(Color[] buffer, OnlineMapsVector2i bufferPosition, int bufferWidth, int bufferHeight, int zoom, List<Vector2> points, Color color) { if (color.a == 0) return; List<Vector2> bufferPoints = new List<Vector2>(); float minX = float.MaxValue; float maxX = float.MinValue; float minY = float.MaxValue; float maxY = float.MinValue; foreach (Vector2 point in points) { Vector2 bufferPoint = (OnlineMapsUtils.LatLongToTilef(point, zoom) - bufferPosition) * OnlineMapsUtils.tileSize; if (bufferPoint.x < minX) minX = bufferPoint.x; if (bufferPoint.x > maxX) maxX = bufferPoint.x; if (bufferPoint.y < minY) minY = bufferPoint.y; if (bufferPoint.y > maxY) maxY = bufferPoint.y; bufferPoints.Add(bufferPoint); } float stY = Mathf.Clamp(minY, 0, bufferHeight); float stX = Mathf.Clamp(minX, 0, bufferWidth); float endY = Mathf.Clamp(maxY, 0, bufferHeight); float endX = Mathf.Clamp(maxX, 0, bufferWidth); int lengthX = Mathf.RoundToInt(endX - stX); int lengthY = Mathf.RoundToInt(endY - stY); Vector2 start = new Vector2(stX, stY); Color clr = new Color(color.r, color.g, color.b, 1); for (int y = 0; y < lengthY; y++) { float bufferY = y + start.y; for (int x = 0; x < lengthX; x++) { float bufferX = x + start.x; if (OnlineMapsUtils.IsPointInPolygon(bufferPoints, bufferX, bufferY)) { int bufferIndex = (int)bufferY * bufferWidth + (int)bufferX; if (color.a == 1) buffer[bufferIndex] = color; else buffer[bufferIndex] = Color.Lerp(buffer[bufferIndex], clr, color.a); } } } }
protected void DrawLineToBuffer(Color[] buffer, OnlineMapsVector2i bufferPosition, int bufferWidth, int bufferHeight, int zoom, List<Vector2> points, Color color, float weight, bool closed) { if (color.a == 0) return; int w = Mathf.RoundToInt(weight); int countOffet = closed ? 0 : 1; for (int j = 0; j < points.Count - countOffet; j++) { int pj = j + 1; if (pj >= points.Count) pj = 0; Vector2 from = OnlineMapsUtils.LatLongToTilef(points[j], zoom) - bufferPosition; Vector2 to = OnlineMapsUtils.LatLongToTilef(points[pj], zoom) - bufferPosition; from *= OnlineMapsUtils.tileSize; to *= OnlineMapsUtils.tileSize; float stY = Mathf.Clamp(Mathf.Min(from.y, to.y) - w, 0, bufferHeight); float stX = Mathf.Clamp(Mathf.Min(from.x, to.x) - w, 0, bufferWidth); float endY = Mathf.Clamp(Mathf.Max(from.y, to.y) + w, 0, bufferHeight); float endX = Mathf.Clamp(Mathf.Max(from.x, to.x) + w, 0, bufferWidth); int strokeOuter2 = w * w; int sqrW = w * w; int lengthX = Mathf.RoundToInt(endX - stX); int lengthY = Mathf.RoundToInt(endY - stY); Vector2 start = new Vector2(stX, stY); for (int y = 0; y < lengthY; y++) { for (int x = 0; x < lengthX; x++) { Vector2 p = new Vector2(x, y) + start; Vector2 center = p + halfVector; float dist = (center - center.NearestPointStrict(from, to)).sqrMagnitude; if (dist <= strokeOuter2) { Color c = Color.black; Vector2[] samples = { p + sampleV1, p + sampleV2, p + sampleV3, p + sampleV4 }; int bufferIndex = (int)p.y * bufferWidth + (int)p.x; Color pc = buffer[bufferIndex]; for (int i = 0; i < 4; i++) { dist = (samples[i] - samples[i].NearestPointStrict(from, to)).sqrMagnitude; if (dist < sqrW) c += color; else c += pc; } c /= 4; buffer[bufferIndex] = c; } } } } }
/// <summary> /// Gets aligned position. /// </summary> /// <param name="pos"> /// Buffer position. /// </param> /// <returns> /// The aligned buffer position. /// </returns> public OnlineMapsVector2i GetAlignedPosition(OnlineMapsVector2i pos) { OnlineMapsVector2i offset = OnlineMapsVector2i.zero; if (align == OnlineMapsAlign.BottomRight || align == OnlineMapsAlign.Right || align == OnlineMapsAlign.TopRight) offset.x = _textureWidth; else if (align == OnlineMapsAlign.Bottom || align == OnlineMapsAlign.Center || align == OnlineMapsAlign.Top) offset.x = _textureWidth / 2; if (align == OnlineMapsAlign.BottomRight || align == OnlineMapsAlign.Bottom || align == OnlineMapsAlign.BottomLeft) offset.y = _textureHeight; else if (align == OnlineMapsAlign.Left || align == OnlineMapsAlign.Center || align == OnlineMapsAlign.Right) offset.y = _textureHeight / 2; if (_rotation == 0) { pos -= offset; } else { float angle = 1 - Mathf.Repeat(_rotation * 360, 360); Matrix4x4 matrix = new Matrix4x4(); matrix.SetTRS(new Vector3(_width / 2, 0, _height / 2), Quaternion.Euler(0, angle, 0), Vector3.one); Vector3 off = matrix.MultiplyPoint(new Vector3(offset.x - _textureWidth / 2, 0, offset.y - _textureHeight / 2)); pos.x -= (int)off.x; pos.y -= (int)off.z; } return pos; }
private void GetElevation() { ignoreGetElevation = true; if (elevationRequest != null) return; elevationBufferPosition = bufferPosition; ignoreGetElevation = false; const int s = OnlineMapsUtils.tileSize; int countX = api.width / s + 2; int countY = api.height / s + 2; Vector2 startCoords = OnlineMapsUtils.TileToLatLong(bufferPosition.x, bufferPosition.y, api.zoom); Vector2 endCoords = OnlineMapsUtils.TileToLatLong(bufferPosition.x + countX, bufferPosition.y + countY, api.zoom); elevationRequestRect = new Rect(startCoords.x, startCoords.y, endCoords.x - startCoords.x, endCoords.y - startCoords.y); if (OnGetElevation == null) { const string urlPattern = "https://dev.virtualearth.net/REST/v1/Elevation/Bounds?bounds={0},{1},{2},{3}&rows=32&cols=32&key={4}"; string url = string.Format(urlPattern, endCoords.y, startCoords.x, startCoords.y, endCoords.x, bingAPI); elevationRequest = OnlineMapsUtils.GetWWW(url); } else OnGetElevation(startCoords, endCoords); }
public override void UpdateControl() { base.UpdateControl(); _bufferPosition = null; if (OnlineMapsTile.tiles == null) return; if (useElevation != _useElevation) { elevationBufferPosition = null; elevationRect = default(Rect); triangles = null; InitMapMesh(); } UpdateMapMesh(); if (drawingsGameObject == null) InitDrawingsMesh(); foreach (OnlineMapsDrawingElement drawingElement in api.drawingElements) { drawingElement.DrawOnTileset(this); } if (marker2DMode == OnlineMapsMarker2DMode.flat) UpdateMarkersMesh(); }
/// <summary> /// Gets aligned offset (in pixels). /// </summary> /// <returns>Aligned offset.</returns> public OnlineMapsVector2i GetAlignOffset() { OnlineMapsVector2i offset = new OnlineMapsVector2i(); if (align == OnlineMapsAlign.BottomRight || align == OnlineMapsAlign.Right || align == OnlineMapsAlign.TopRight) offset.x = _textureWidth; else if (align == OnlineMapsAlign.Bottom || align == OnlineMapsAlign.Center || align == OnlineMapsAlign.Top) offset.x = _textureWidth / 2; if (align == OnlineMapsAlign.BottomRight || align == OnlineMapsAlign.Bottom || align == OnlineMapsAlign.BottomLeft) offset.y = _textureHeight; else if (align == OnlineMapsAlign.Left || align == OnlineMapsAlign.Center || align == OnlineMapsAlign.Right) offset.y = _textureHeight / 2; return offset; }
private void UpdateMesh() { _bufferPosition = null; _alpha = alpha; int w1 = api.tilesetWidth / OnlineMapsUtils.tileSize; int h1 = api.tilesetHeight / OnlineMapsUtils.tileSize; int subMeshVX = 1; int subMeshVZ = 1; Vector2 subMeshSize = new Vector2(api.tilesetSize.x / w1, api.tilesetSize.y / h1); Vector2 topLeftPosition = api.topLeftPosition; Vector2 bottomRightPosition = api.bottomRightPosition; Vector2 tlPos = OnlineMapsUtils.LatLongToTilef(topLeftPosition, api.zoom); Vector2 pos = tlPos - bufferPosition; int maxX = (2 << api.zoom) / 2; if (pos.x >= maxX) pos.x -= maxX; Vector3 startPos = new Vector3(subMeshSize.x * pos.x, 0, -subMeshSize.y * pos.y); int w = w1 + 2; int h = h1 + 2; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { UpdateMapSubMesh(x, y, w, h, subMeshSize, subMeshVX, subMeshVZ, startPos, 0, topLeftPosition, bottomRightPosition); } } overlayMesh.vertices = vertices; overlayMesh.uv = uv; for (int i = 0; i < overlayMesh.subMeshCount; i++) overlayMesh.SetTriangles(overlayMesh.GetTriangles(i), i); overlayMesh.RecalculateBounds(); }
private void GetFrontBufferPosition(double px, double py, OnlineMapsVector2i _bufferPosition, int zoom, int apiWidth, int apiHeight) { OnlineMapsVector2i pos = GetBackBufferPosition(px, py, _bufferPosition, zoom, apiWidth, apiHeight); int ix = pos.x; int iy = pos.y; if (iy < 0) iy = 0; else if (iy >= height - apiHeight) iy = height - apiHeight; frontBufferPosition = new OnlineMapsVector2i(ix, iy); }
private void SetColorToBuffer(Color clr, OnlineMapsVector2i ip, int y, int x) { if (clr.a == 0) return; if (clr.a < 1) { float alpha = clr.a; clr.a = 1; clr = Color.Lerp(backBuffer[(ip.y + y) * width + ip.x + x], clr, alpha); } backBuffer[(ip.y + y) * width + ip.x + x] = clr; }
private void InitTiles(int zoom, OnlineMapsBufferZoom activeZoom, int countX, OnlineMapsVector2i pos, int countY, int maxY, List<OnlineMapsTile> newBaseTiles) { //IEnumerable<OnlineMapsTile> tiles = OnlineMapsTile.tiles.Where(t => t.provider == api.provider && t.zoom == activeZoom.id && t.type == api.type); IEnumerable<OnlineMapsTile> tiles = activeZoom.tiles; int maxX = 1 << bufferZoom; for (int x = 0; x < countX; x++) { int px = x + pos.x; if (px < 0) px += maxX; else if (px >= maxX) px -= maxX; for (int y = 0; y < countY; y++) InitTile(zoom, activeZoom, pos, maxY, newBaseTiles, y, tiles, px); } }
protected void DrawLineToBuffer(Color[] buffer, OnlineMapsVector2i bufferPosition, int bufferWidth, int bufferHeight, int zoom, List<Vector2> points, Color color, float weight, bool closed) { if (color.a == 0) return; double sx, sy; OnlineMapsUtils.LatLongToTiled(tlx, tly, zoom, out sx, out sy); int maxX = 1 << zoom; int off = closed ? 1 : 0; List<Vector2> localPoints = new List<Vector2>(); double ppx = 0; for (int i = 0; i < points.Count + off; i++) { int ci = i; if (ci >= points.Count) ci -= points.Count; double px, py; OnlineMapsUtils.LatLongToTiled(points[ci].x, points[ci].y, zoom, out px, out 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 + sx; double ry1 = py + sy; Vector2 np = new Vector2((float)rx1, (float)ry1); localPoints.Add(np); } int w = Mathf.RoundToInt(weight); for (int j = 0; j < localPoints.Count - 1; j++) { Vector2 p1 = localPoints[j] - bufferPosition; Vector2 p2 = localPoints[j + 1] - bufferPosition; if (p1.x > maxX && p2.x > maxX) { p1.x -= maxX; p2.x -= maxX; } Vector2 from = p1 * OnlineMapsUtils.tileSize; Vector2 to = p2 * OnlineMapsUtils.tileSize; float stY = Mathf.Clamp(Mathf.Min(from.y, to.y) - w, 0, bufferHeight); float stX = Mathf.Clamp(Mathf.Min(from.x, to.x) - w, 0, bufferWidth); float endY = Mathf.Clamp(Mathf.Max(from.y, to.y) + w, 0, bufferHeight); float endX = Mathf.Clamp(Mathf.Max(from.x, to.x) + w, 0, bufferWidth); int strokeOuter2 = w * w; int sqrW = w * w; int lengthX = Mathf.RoundToInt(endX - stX); int lengthY = Mathf.RoundToInt(endY - stY); Vector2 start = new Vector2(stX, stY); for (int y = 0; y < lengthY; y++) { for (int x = 0; x < lengthX; x++) { Vector2 p = new Vector2(x, y) + start; Vector2 center = p + halfVector; float dist = (center - center.NearestPointStrict(from, to)).sqrMagnitude; if (dist <= strokeOuter2) { Color c = Color.black; Vector2[] samples = { p + sampleV1, p + sampleV2, p + sampleV3, p + sampleV4 }; int bufferIndex = (int)p.y * bufferWidth + (int)p.x; Color pc = buffer[bufferIndex]; for (int i = 0; i < 4; i++) { dist = (samples[i] - samples[i].NearestPointStrict(from, to)).sqrMagnitude; if (dist < sqrW) c += Color.Lerp(pc, color, color.a); else c += pc; } c /= 4; buffer[bufferIndex] = c; } } } } }
private bool UpdateBackBuffer(double px, double py, int zoom, bool fullRedraw) { const int s = OnlineMapsUtils.tileSize; int countX = api.width / s + 2; int countY = api.height / s + 2; OnlineMapsVector2i pos = OnlineMapsUtils.LatLongToTile(px, py, zoom); pos.x -= countX / 2; pos.y -= countY / 2; int maxY = (2 << zoom) / 2; if (pos.y < 0) pos.y = 0; if (pos.y >= maxY - countY - 1) pos.y = maxY - countY - 1; if (api.target == OnlineMapsTarget.texture) { if (frontBuffer == null || frontBuffer.Length != api.width * api.height) { frontBuffer = new Color[api.width * api.height]; fullRedraw = true; } if (backBuffer == null || width != countX * s || height != countY * s) { width = countX * s; height = countY * s; backBuffer = new Color[height * width]; fullRedraw = true; } } if (!updateBackBuffer && !fullRedraw && bufferZoom == zoom && bufferPosition != null && bufferPosition == pos) return false; updateBackBuffer = false; bufferPosition = pos; bufferZoom = zoom; OnlineMapsBufferZoom activeZoom = GetActiveZoom(zoom); List<OnlineMapsTile> newBaseTiles = new List<OnlineMapsTile>(); lock (OnlineMapsTile.tiles) { foreach (OnlineMapsTile tile in OnlineMapsTile.tiles) tile.used = false; InitTiles(zoom, activeZoom, countX, pos, countY, maxY, newBaseTiles); if (!api.useCurrentZoomTiles) { List<OnlineMapsTile> newParentTiles = CreateParents(newBaseTiles, zoom - 1); if (zoom - 2 > 2) { newParentTiles = CreateParents(newParentTiles, zoom - 2); if (zoom - 3 > 2) CreateParents(newParentTiles, zoom - 3); } } if (api.target == OnlineMapsTarget.texture) SetMarkersToBuffer(api.markers); } needUnloadTiles = true; return true; }
private void InitTile(int zoom, OnlineMapsBufferZoom activeZoom, OnlineMapsVector2i pos, int maxY, List<OnlineMapsTile> newBaseTiles, int y, List<OnlineMapsTile> ts, int px) { int py = y + pos.y; if (py < 0 || py >= maxY) return; OnlineMapsTile tile = ts.FirstOrDefault(t => t.x == px && t.y == py); if (tile == null) { OnlineMapsTile parent = OnlineMapsTile.tiles.FirstOrDefault( t => t.zoom == zoom - 1 && t.x == px / 2 && t.y == py / 2); tile = new OnlineMapsTile(px, py, zoom, api, parent) {OnSetColor = OnTileSetColor}; activeZoom.tiles.Add(tile); } newBaseTiles.Add(tile); tile.used = true; SetBufferTile(tile); }
public override void Draw(Color[] buffer, OnlineMapsVector2i bufferPosition, int bufferWidth, int bufferHeight, int zoom) { if (!visible) return; FillPoly(buffer, bufferPosition, bufferWidth, bufferHeight, zoom, points, backgroundColor); DrawLineToBuffer(buffer, bufferPosition, bufferWidth, bufferHeight, zoom, points, borderColor, borderWeight, true); }
private OnlineMapsVector2i GetBackBufferPosition(Vector2 position, OnlineMapsVector2i _bufferPosition, int zoom, int apiWidth, int apiHeight) { Vector2 pos = OnlineMapsUtils.LatLongToTilef(position, zoom); int countX = apiWidth / OnlineMapsUtils.tileSize + 2; int countY = apiHeight / OnlineMapsUtils.tileSize + 2; pos.x -= countX / 2f + _bufferPosition.x - 1; pos.y -= countY / 2f + _bufferPosition.y - 1; int ix = (int) ((pos.x / countX) * width); int iy = (int) ((pos.y / countY) * height); return new OnlineMapsVector2i(ix, iy); }