using System;
using UnityEngine;
public class MercatorProjection
{
static double MERCATOR_RANGE = 256;
Point pixelsOrigin;
double pixelsPerLonDegree;
double pixelsPerLonRadian;
public MercatorProjection()
{
pixelsOrigin = new Point(MERCATOR_RANGE / 2, MERCATOR_RANGE / 2);
pixelsPerLonDegree = MERCATOR_RANGE / 360;
pixelsPerLonRadian = MERCATOR_RANGE / (2 * Math.PI);
}
double bound(double value, double opt_min, double opt_max)
{
if (opt_min != 0)
value = Math.Max(value, opt_min);
if (opt_max != 0)
value = Math.Min(value, opt_max);
return value;
}
double degreesToRadians(double deg)
{
return deg * (Math.PI / 180);
}
double radiansToDegrees(double rad)
{
return rad / (Math.PI / 180);
}
Point fromLatLonToPoint(Coordinates latLon)
{
Point point = new Point();
Point origin = pixelsOrigin;
point.X = origin.X + latLon.Longitude * pixelsPerLonDegree;
double sinY = bound(Math.Sin(degreesToRadians(latLon.Latitude)), -0.9999, 0.9999);
point.Y = origin.Y + 0.5 * Math.Log((1 + sinY) / (1 - sinY)) * -pixelsPerLonRadian;
return point;
}
Coordinates fromPointToLatlon(Point point)
{
Point origin = pixelsOrigin;
Coordinates latLon = new Coordinates();
latLon.Latitude = (point.X - origin.X) / pixelsPerLonDegree;
double latRadians = (point.Y - origin.Y) / -pixelsPerLonRadian;
latLon.Longitude = radiansToDegrees(2 * Math.Atan(Math.Exp(latRadians)) - Math.PI / 2);
return latLon;
}
public void GetCorners(Coordinates center, float zoom, float mapWidth, float mapHeight)
{
double scale = Math.Pow(2, zoom);
Point centerPx = fromLatLonToPoint(center);
Point SWPoint = new Point(centerPx.X - (mapWidth / 2) / scale, centerPx.Y + (mapHeight / 2) / scale);
Coordinates SWLatLon = fromPointToLatlon(SWPoint);
Debug.Log(SWLatLon.Latitude + " " + SWLatLon.Longitude + " " + SWPoint.X + " " + SWPoint.Y);
}
}
MercatorProjection.GetCorners(new Coordinates(Coordinates.Longitude, Coordinates.Latitude), 16, 640, 640);
using System;
public static class GoogleMapsAPI{
static GoogleMapsAPI()
{
OriginX = TileSize / 2;
OriginY = TileSize / 2;
PixelsPerLonDegree = TileSize / 360.0;
PixelsPerLonRadian = TileSize / (2 * Math.PI);
}
public static int TileSize = 256;
public static double OriginX, OriginY;
public static double PixelsPerLonDegree;
public static double PixelsPerLonRadian;
public static double DegreesToRadians(double deg)
{
return deg * Math.PI / 180.0;
}
public static double RadiansToDegrees(double rads)
{
return rads * 180.0 / Math.PI;
}
public static double Bound(double value, double min, double max)
{
value = Math.Min(value, max);
return Math.Max(value, min);
}
//From Lat, Lon to World Coordinate X, Y. I'm being explicit in assigning to
//X and Y properties.
public static Coordinate Mercator(double latitude, double longitude)
{
double siny = Bound(Math.Sin(DegreesToRadians(latitude)), -.9999, .9999);
Coordinate c = new Coordinate(0, 0);
c.X = OriginX + longitude * PixelsPerLonDegree;
c.Y = OriginY + .5 * Math.Log((1 + siny) / (1 - siny)) * -PixelsPerLonRadian;
return c;
}
//From World Coordinate X, Y to Lat, Lon. I'm being explicit in assigning to
//Latitude and Longitude properties.
public static Coordinate InverseMercator(double x, double y)
{
Coordinate c = new Coordinate(0, 0);
c.Longitude = (x - OriginX) / PixelsPerLonDegree;
double latRadians = (y - OriginY) / -PixelsPerLonRadian;
c.Latitude = RadiansToDegrees(Math.Atan(Math.Sinh(latRadians)));
return c;
}
public static MapCoordinates GetBounds(Coordinate center, int zoom, int mapWidth, int mapHeight)
{
var scale = Math.Pow(2, zoom);
var centerWorld = Mercator(center.Latitude, center.Longitude);
var centerPixel = new Coordinate(0, 0);
centerPixel.X = centerWorld.X * scale;
centerPixel.Y = centerWorld.Y * scale;
var NEPixel = new Coordinate(0, 0);
NEPixel.X = centerPixel.X + mapWidth / 2.0;
NEPixel.Y = centerPixel.Y - mapHeight / 2.0;
var SWPixel = new Coordinate(0, 0);
SWPixel.X = centerPixel.X - mapWidth / 2.0;
SWPixel.Y = centerPixel.Y + mapHeight / 2.0;
var NEWorld = new Coordinate(0, 0);
NEWorld.X = NEPixel.X / scale;
NEWorld.Y = NEPixel.Y / scale;
var SWWorld = new Coordinate(0, 0);
SWWorld.X = SWPixel.X / scale;
SWWorld.Y = SWPixel.Y / scale;
var NELatLon = InverseMercator(NEWorld.X, NEWorld.Y);
var SWLatLon = InverseMercator(SWWorld.X, SWWorld.Y);
return new MapCoordinates() { NorthEast = NELatLon, SouthWest = SWLatLon };
}
}
public class MapCoordinates
{
public Coordinate SouthWest { get; set; }
public Coordinate NorthEast { get; set; }
}
public class Coordinate
{
public double Latitude { get; set; }
public double Longitude { get; set; }
public double Y { get { return Latitude; } set { Latitude = value; } }
public double X { get { return Longitude; } set { Longitude = value; } }
public Coordinate(double lng, double lat)
{
Latitude = lat;
Longitude = lng;
}
public override string ToString()
{
return Math.Round(X, 6).ToString() + ", " + Math.Round(Y, 6).ToString();
}
}
Coordinates = new Coordinate(51.445691, 5.460318);
var result = GoogleMapsAPI.GetBounds(Coordinates, 16, 640, 640);
Debug.Log("SouthWest: "+result.SouthWest.ToString() + " NorthEast: "+result.NorthEast.ToString());
西南:51.438825,5.453483东北:51.452557,5.467153
西南:12.015251、8.527824东北:12.028983、8.541404
后来我试过世界上许多其他地区,但往往是很远的地方,有时甚至数百英里。所以也许尼日利亚的这个小镇只是一个巧合,但我希望有人能给我一个解释和/或解决办法。
特别感谢peterjb和marcelo
SW-HTTPD is a simple, secure, and robust HyperText Transfer Protocol Daemon Written in the C programming language. It implements the bare minimum of HTTP 1.1 necessary to be a productive web server.
特性 简单的与webpack4使用 不需要提供ServiceWorker文件 提供了一个回调API,当webpack的输出文件发生变化时,你可以做一些处理 安装 npm install --save-dev webpack-sw-plugin 执行案例 npm run example 在浏览器内打开localhost:3000 使用教程 快速上手 webpack.config.js const W
我试图使用,但我一定是做错了什么! 我主要使用github repo提供的演示代码,似乎无法获得应用程序的更新。一旦第一次缓存,它就不会检查新版本。 我希望在发布新的服务人员时,浏览器会请求新的服务人员,并在后台相应地更新缓存。然后使用示例中的注册码,我将能够提示用户刷新并从其新刷新的缓存中获取最新版本。 如果有人能为我指出正确的方向,我将不胜感激。 为了说明这个问题,我在这里创建了一个单独的示例
我试图在javascript中为fetch创建一个拦截器(更具体地说是React)。它应该从每次调用的fetch中获取结果,如果是401错误,它应该向另一个路由发起新的fetch调用,以获取cookie(刷新令牌)。然后,应该再次尝试原始的fetch调用(因为现在用户已经登录)。 我已经成功地触发了新的fetch调用,并为每个调用发回了cookie,但我遇到了以下两个问题: 我似乎在使用async
我使用Zulu openJdk 11进行ARM。我试过在IntelliJ和VsCode中进行对接,得到相同的错误。(我使用的是JavaFx SDK 11.0.2)错误消息(来自visual studio代码的截图)
info 一个 webpack 插件,解决 service-worker.js 的注册和更新问题。 Lavas 解决方案默认集成该插件用来实现 Service Worker 文件的注册及缓存更新机制,默认只在 build 生产环境下构建生效。 github: https://github.com/lavas-project/sw-register-webpack-plugin.git 背景 PWA