public override Vector2 GetCoords(Vector2 position) { if (!RectTransformUtility.RectangleContainsScreenPoint(image.rectTransform, position, worldCamera)) { return(Vector2.zero); } Vector2 point; RectTransformUtility.ScreenPointToLocalPointInRectangle(image.rectTransform, position, worldCamera, out point); Rect rect = image.GetPixelAdjustedRect(); Vector2 size = (rect.max - point); size.x = size.x / rect.size.x; size.y = size.y / rect.size.y; Vector2 r = new Vector2((size.x - .5f), (size.y - .5f)); int countX = api.width / OnlineMapsUtils.tileSize; int countY = api.height / OnlineMapsUtils.tileSize; double px, py; api.GetPosition(out px, out py); OnlineMapsUtils.LatLongToTiled(px, py, api.zoom, out px, out py); px -= countX * r.x; py += countY * r.y; OnlineMapsUtils.TileToLatLong(px, py, api.zoom, out px, out py); return(new Vector2((float)px, (float)py)); }
public override bool GetCoords(out double lng, out double lat, Vector2 position) { RaycastHit hit; lng = lat = 0; if (!Physics.Raycast(Camera.main.ScreenPointToRay(position), out hit)) { return(false); } if (hit.collider.gameObject != gameObject) { return(false); } Vector3 size = (cl.bounds.max - hit.point); size.x = size.x / cl.bounds.size.x; size.y = size.y / cl.bounds.size.y; Vector2 r = new Vector3((size.x - .5f), (size.y - .5f)); int countX = api.width / OnlineMapsUtils.tileSize; int countY = api.height / OnlineMapsUtils.tileSize; double px, py; api.GetPosition(out px, out py); OnlineMapsUtils.LatLongToTiled(px, py, api.zoom, out px, out py); px -= countX * r.x; py += countY * r.y; OnlineMapsUtils.TileToLatLong(px, py, api.zoom, out lng, out lat); return(true); }
private Vector2 GetCoords3D(Vector2 position) { RaycastHit hit; if (!Physics.Raycast(Camera.main.ScreenPointToRay(position), out hit)) { return(Vector2.zero); } if (hit.collider.gameObject != gameObject) { return(Vector2.zero); } Vector3 size = (cl.bounds.max - hit.point); size.x = size.x / cl.bounds.size.x; size.y = size.y / cl.bounds.size.y; Vector2 r = new Vector3((size.x - .5f), (size.y - .5f)); int countX = api.width / OnlineMapsUtils.tileSize; int countY = api.height / OnlineMapsUtils.tileSize; double px, py; api.GetPosition(out px, out py); OnlineMapsUtils.LatLongToTiled(px, py, api.zoom, out px, out py); px -= countX * r.x; py += countY * r.y; OnlineMapsUtils.TileToLatLong(px, py, api.zoom, out px, out py); return(new Vector2((float)px, (float)py)); }
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)); }
public override bool GetCoords(out double lng, out double lat, Vector2 position) { Rect rect = screenRect; int countX = api.texture.width / OnlineMapsUtils.tileSize; int countY = api.texture.height / OnlineMapsUtils.tileSize; double px, py; api.GetPosition(out px, out py); OnlineMapsUtils.LatLongToTiled(px, py, api.zoom, out px, out py); double rx = (rect.center.x - position.x) / rect.width * 2; double ry = (rect.center.y - position.y) / rect.height * 2; px -= countX / 2f * rx; py += countY / 2f * ry; OnlineMapsUtils.TileToLatLong(px, py, api.zoom, out lng, out lat); return(true); }
public override Vector2 GetCoords(Vector2 position) { Rect rect = screenRect; int countX = api.texture.width / OnlineMapsUtils.tileSize; int countY = api.texture.height / OnlineMapsUtils.tileSize; double px, py; api.GetPosition(out px, out py); OnlineMapsUtils.LatLongToTiled(px, py, api.zoom, out px, out py); float rx = (rect.center.x - position.x) / rect.width * 2; float ry = (rect.center.y - position.y) / rect.height * 2; px -= countX / 2f * rx; py += countY / 2f * ry; OnlineMapsUtils.TileToLatLong(px, py, api.zoom, out px, out py); return(new Vector2((float)px, (float)py)); }
/// <summary> /// Converts geographical coordinate to position in the scene relative to the top-left corner of the map in map space. /// </summary> /// <param name="lng">Longitude</param> /// <param name="lat">Latitude</param> /// <param name="px">Relative position X</param> /// <param name="py">Relative position Y</param> public virtual void GetPosition(double lng, double lat, out double px, out double py) { double tx, ty; double dx, dy, dtx, dty; OnlineMapsUtils.LatLongToTiled(lng, lat, api.zoom, out dx, out dy); api.GetTopLeftPosition(out tx, out ty); OnlineMapsUtils.LatLongToTiled(tx, ty, api.zoom, out dtx, out dty); dx -= dtx; dy -= dty; int maxX = 1 << api.zoom; if (dx < -maxX / 2) { dx += maxX; } px = dx * OnlineMapsUtils.tileSize; py = dy * OnlineMapsUtils.tileSize; }
public override bool GetCoords(out double lng, out double lat, Vector2 position) { RaycastHit hit; lng = lat = 0; if (!Physics.Raycast(activeCamera.ScreenPointToRay(position), out hit)) { return(false); } if (hit.collider.gameObject != gameObject) { return(false); } Renderer render = hit.collider.GetComponent <Renderer>(); MeshCollider meshCollider = hit.collider as MeshCollider; if (render == null || render.sharedMaterial == null || render.sharedMaterial.mainTexture == null || meshCollider == null) { return(false); } Vector2 r = hit.textureCoord; r.x = r.x - 0.5f; r.y = r.y - 0.5f; int countX = api.width / OnlineMapsUtils.tileSize; int countY = api.height / OnlineMapsUtils.tileSize; double px, py; api.GetPosition(out px, out py); OnlineMapsUtils.LatLongToTiled(px, py, api.zoom, out px, out py); px += countX * r.x; py -= countY * r.y; OnlineMapsUtils.TileToLatLong(px, py, api.zoom, out lng, out lat); return(true); }
/// <summary> /// Updates billboard markers. /// </summary> protected void UpdateMarkersBillboard() { if (markersGameObject == null) { InitMarkersMesh(); } if (markerBillboards == null) { markerBillboards = new Dictionary <int, OnlineMapsMarkerBillboard>(); } double tlx, tly, brx, bry; api.GetTopLeftPosition(out tlx, out tly); api.GetBottomRightPosition(out brx, out bry); if (brx < tlx) { brx += 360; } int maxX = (2 << api.buffer.apiZoom) / 2; double px, py; OnlineMapsUtils.LatLongToTiled(tlx, tly, api.zoom, out px, out py); float yScale = GetBestElevationYScale(tlx, tly, brx, bry); Bounds mapBounds = cl.bounds; Vector3 positionOffset = transform.position - mapBounds.min; Vector3 size = mapBounds.size; size = transform.rotation * size; if (api.target == OnlineMapsTarget.tileset) { positionOffset.x -= size.x; } foreach (KeyValuePair <int, OnlineMapsMarkerBillboard> billboard in markerBillboards) { billboard.Value.used = false; } foreach (OnlineMapsMarker marker in api.markers) { if (!marker.enabled || !marker.range.InRange(api.zoom)) { continue; } float mx = marker.position.x; if (!(((mx > tlx && mx < brx) || (mx + 360 > tlx && mx + 360 < brx) || (mx - 360 > tlx && mx - 360 < brx)) && marker.position.y < tly && marker.position.y > bry)) { continue; } int markerHashCode = marker.GetHashCode(); OnlineMapsMarkerBillboard markerBillboard = null; if (!markerBillboards.ContainsKey(markerHashCode)) { markerBillboard = OnlineMapsMarkerBillboard.Create(marker); markerBillboard.transform.parent = markersGameObject.transform; markerBillboards.Add(markerHashCode, markerBillboard); } else { markerBillboard = markerBillboards[markerHashCode]; } float sx = size.x / api.width * marker2DSize * marker.scale; float sz = size.z / api.height * marker2DSize * marker.scale; float s = Mathf.Max(sx, sz); markerBillboard.transform.localScale = new Vector3(-s, s, s); Vector2 p = OnlineMapsUtils.LatLongToTilef(marker.position, api.buffer.apiZoom); p.x = Mathf.Repeat(p.x - (float)px, maxX); p.y -= (float)py; float x = -p.x / api.width * OnlineMapsUtils.tileSize * size.x + positionOffset.x; float z = p.y / api.height * OnlineMapsUtils.tileSize * size.z - positionOffset.z; float y = GetElevationValue(x, z, yScale, tlx, tly, brx, bry); markerBillboard.transform.localPosition = transform.rotation * new Vector3(x, y, z); markerBillboard.used = true; } List <int> keysForRemove = new List <int>(); foreach (KeyValuePair <int, OnlineMapsMarkerBillboard> billboard in markerBillboards) { if (!billboard.Value.used) { billboard.Value.Dispose(); keysForRemove.Add(billboard.Key); } } foreach (int key in keysForRemove) { markerBillboards.Remove(key); } }
public override void Update(double tlx, double tly, double brx, double bry, int zoom) { if (instance == null) { Debug.Log("No instance"); return; } if (!range.InRange(zoom)) { enabled = false; } else if (position.y > tly || position.y < bry) { enabled = false; } else if (tlx < brx && (position.x < tlx || position.x > brx)) { enabled = false; } else if (tlx > brx && position.x < tlx && position.x > brx) { enabled = false; } else { enabled = true; } if (!enabled) { return; } if (_prefab != prefab) { Reinit(tlx, tly, brx, bry, zoom); } double mx, my; OnlineMapsUtils.LatLongToTiled(position.x, position.y, zoom, out mx, out my); double ttlx, ttly, tbrx, tbry; OnlineMapsUtils.LatLongToTiled(tlx, tly, zoom, out ttlx, out ttly); OnlineMapsUtils.LatLongToTiled(brx, bry, zoom, out tbrx, out tbry); int maxX = (2 << zoom) / 2; OnlineMaps api = OnlineMaps.instance; Bounds bounds = api.GetComponent <Collider>().bounds; double sx = tbrx - ttlx; if (sx < 0) { sx += maxX; } double mpx = mx - ttlx; if (mpx < 0) { mpx += maxX; } double px = mpx / sx; double pz = (ttly - my) / (ttly - tbry); _relativePosition = new Vector3((float)px, 0, (float)pz); if (OnlineMapsControlBase.instance is OnlineMapsTileSetControl) { px = -api.tilesetSize.x / 2 - (px - 0.5) * api.tilesetSize.x; pz = api.tilesetSize.y / 2 + (pz - 0.5) * api.tilesetSize.y; } else { Vector3 center = bounds.center; Vector3 size = bounds.size; px = center.x - (px - 0.5) * size.x - api.transform.position.x; pz = center.z + (pz - 0.5) * size.z - api.transform.position.z; } Vector3 oldPosition = instance.transform.localPosition; float y = 0; if (OnlineMapsControlBase.instance is OnlineMapsTileSetControl) { OnlineMapsTileSetControl control = OnlineMapsTileSetControl.instance; y = control.GetElevationValue((float)px, (float)pz, control.GetBestElevationYScale(tlx, tly, brx, bry), tlx, tly, brx, bry); } Vector3 newPosition = new Vector3((float)px, y, (float)pz); instance.transform.localPosition = newPosition; if (oldPosition != newPosition && OnPositionChanged != null) { OnPositionChanged(this); } }
protected List <Vector2> GetLocalPoints(List <Vector2> points, bool closed = false) { double sx, sy; OnlineMapsUtils.LatLongToTiled(tlx, tly, api.buffer.apiZoom, out sx, out sy); int maxX = 1 << api.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, api.buffer.apiZoom, 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 * OnlineMapsUtils.tileSize) / api.tilesetWidth * api.tilesetSize.x; double ry1 = (py * OnlineMapsUtils.tileSize) / api.tilesetHeight * api.tilesetSize.y; Vector2 np = new Vector2((float)rx1, (float)ry1); localPoints.Add(np); } return(localPoints); }
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 void UpdateBuildingsPosition() { Bounds bounds = new Bounds(); Vector2 topLeftPosition = OnlineMaps.instance.topLeftPosition; Vector2 bottomRightPosition = OnlineMaps.instance.bottomRightPosition; bounds.min = new Vector3(topLeftPosition.x, bottomRightPosition.y); bounds.max = new Vector3(bottomRightPosition.x, topLeftPosition.y); List <string> unusedKeys = new List <string>(); bool useElevation = OnlineMapsTileSetControl.instance.useElevation; foreach (KeyValuePair <string, OnlineMapsBuildingBase> building in buildings) { if (!bounds.Intersects(building.Value.boundsCoords)) { unusedKeys.Add(building.Key); } else { if (useElevation) { Vector3 newPosition = OnlineMapsTileSetControl.instance.GetWorldPositionWithElevation(building.Value.centerCoordinates, topLeftPosition, bottomRightPosition); building.Value.transform.position = newPosition; } else { Vector3 newPosition = OnlineMapsTileSetControl.instance.GetWorldPosition(building.Value.centerCoordinates); building.Value.transform.position = newPosition; } } } List <string> usedKeys = new List <string>(); List <string> destroyKeys = new List <string>(); double px, py; api.GetPosition(out px, out py); OnlineMapsUtils.LatLongToTiled(px, py, api.zoom, out px, out py); float maxDistance = Mathf.Sqrt(Mathf.Pow(api.width / 2 / OnlineMapsUtils.tileSize, 2) + Mathf.Pow(api.height / 2 / OnlineMapsUtils.tileSize, 2)) * 2; foreach (KeyValuePair <string, OnlineMapsBuildingBase> building in unusedBuildings) { OnlineMapsBuildingBase value = building.Value; if (bounds.Intersects(value.boundsCoords)) { usedKeys.Add(building.Key); Vector3 newPosition = OnlineMapsTileSetControl.instance.GetWorldPosition(value.centerCoordinates); value.transform.position = newPosition; } else { Vector2 buildingTilePos = OnlineMapsUtils.LatLongToTilef(value.centerCoordinates, api.zoom); if ((buildingTilePos - new Vector2((float)px, (float)py)).magnitude > maxDistance) { destroyKeys.Add(building.Key); } } } foreach (string key in unusedKeys) { OnlineMapsBuildingBase value = buildings[key]; value.gameObject.SetActive(false); unusedBuildings.Add(key, value); buildings.Remove(key); } foreach (string key in usedKeys) { OnlineMapsBuildingBase value = unusedBuildings[key]; if (maxActiveBuildings > 0 && buildings.Count >= maxActiveBuildings) { break; } if (OnShowBuilding != null && !OnShowBuilding(value)) { continue; } value.gameObject.SetActive(true); buildings.Add(key, value); unusedBuildings.Remove(key); } foreach (string key in destroyKeys) { OnlineMapsBuildingBase value = unusedBuildings[key]; if (OnBuildingDispose != null) { OnBuildingDispose(value); } DestroyImmediate(value.gameObject); unusedBuildings.Remove(key); } if (destroyKeys.Count > 0) { OnlineMaps.instance.needGC = true; } }