protected override void GetCenterTile(int tileCountOnX, int tileCountOnY, out int tileX, out int tileY, out float offsetX, out float offsetZ) { int[] tileCoordinates = GeoHelpers.WGS84ToTile(Map.CenterWGS84[0], Map.CenterWGS84[1], Map.RoundedZoom); double[] centerTile = GeoHelpers.TileToWGS84(tileCoordinates[0], tileCoordinates[1], Map.RoundedZoom); double[] centerTileMeters = Map.WGS84ToEPSG900913Transform.Transform(centerTile); //GeoHelpers.WGS84ToMeters(centerTile[0], centerTile[1]); tileX = tileCoordinates[0]; tileY = tileCoordinates[1]; offsetX = Map.RoundedHalfMapScale / 2.0f - (float)(Map.CenterEPSG900913[0] - centerTileMeters[0]) * Map.RoundedScaleMultiplier; offsetZ = -Map.RoundedHalfMapScale / 2.0f - (float)(Map.CenterEPSG900913[1] - centerTileMeters[1]) * Map.RoundedScaleMultiplier; }
protected override string GetTileURL(int tileX, int tileY, int roundedZoom) { double[] tile = GeoHelpers.TileToWGS84(tileX, tileY, roundedZoom); double[] tileMeters = Map.WGS84ToEPSG900913Transform.Transform(tile); //GeoHelpers.WGS84ToMeters(tile[0], tile[1]); float tileSize = Map.TileResolution * Map.RoundedMetersPerPixel; double[] min = Map.EPSG900913ToWGS84Transform.Transform(new double[2] { tileMeters[0], tileMeters[1] - tileSize }); //GeoHelpers.MetersToWGS84(xmin, ymin); double[] max = Map.EPSG900913ToWGS84Transform.Transform(new double[2] { tileMeters[0] + tileSize, tileMeters[1] }); //GeoHelpers.MetersToWGS84(xmax, ymax); return(baseURL + (baseURL.EndsWith("?") ? "" : "?") + "SERVICE=WMS&REQUEST=GetMap&VERSION=1.1.1&LAYERS=" + layers + "&STYLES=&SRS=" + srsName + "&BBOX=" + min[0] + "," + min[1] + "," + max[0] + "," + max[1] + "&WIDTH=" + Map.TileResolution + "&HEIGHT=" + Map.TileResolution + "&FORMAT=" + format); }
private void UpdateInternals() { // FIXME: the half map scale is a value used throughout the implementation to rule the camera elevation // and the size/scale of the tiles, it depends on fixed tile size and resolution (here 256 and 72) so I am not // sure it would work for a tile layer with different values... // maybe there is a way to take the values out of the calculations and reintroduce them on Layer level... // FIXME: the 'division by 20000' helps the values to be kept in range for the Unity3D engine, not sure // this is the right approach either, feels kinda voodooish... halfMapScale = GeoHelpers.OsmZoomLevelToMapScale(currentZoom, /*(float)centerWGS84[1]*/ 0.0f, tileResolution, 72) / scaleDivider; roundedHalfMapScale = GeoHelpers.OsmZoomLevelToMapScale(roundedZoom, (float)/*(float)centerWGS84[1]*/ 0.0f, tileResolution, 72) / scaleDivider; metersPerPixel = GeoHelpers.MetersPerPixel(0.0f, (float)currentZoom); roundedMetersPerPixel = GeoHelpers.MetersPerPixel(0.0f, (float)roundedZoom); // FIXME: another voodoish value to help converting meters (EPSG 900913) to Unity3D world coordinates scaleMultiplier = halfMapScale / (metersPerPixel * tileResolution); roundedScaleMultiplier = roundedHalfMapScale / (roundedMetersPerPixel * tileResolution); }
// <summary> // Zooms the map. // </summary> public void Zoom(float zoomSpeed) { // apply the zoom CurrentZoom += 4.0f * zoomSpeed * Time.deltaTime; // move the camera // FIXME: the camera jumps on the first zoom when tilted, 'cause cam altitude and zoom value are unsynced by the rotation Transform cameraTransform = currentCamera.transform; float y = GeoHelpers.OsmZoomLevelToMapScale(currentZoom, 0.0f, tileResolution, 72) / scaleDivider * screenScale; float t = y / cameraTransform.forward.y; cameraTransform.position = new Vector3( t * cameraTransform.forward.x, y, t * cameraTransform.forward.z); // set the update flag to tell the behaviour the user is manipulating the map hasMoved = true; IsDirty = true; }