百度地图和高德地图坐标系的互相转换 四种Sandcastle方法生成c#.net帮助类帮助文档 文档API生成神器SandCastle使用心得 ASP.NET Core

百度地图和高德地图坐标系的互相转换

 

GPS、谷歌、百度、高德坐标相互转换

1、在进行地图开发过程当中,咱们通常能接触到如下三种类型的地图坐标系:

1.WGS-84原始坐标系,通常用国际GPS纪录仪记录下来的经纬度,经过GPS定位拿到的原始经纬度,Google和高德地图定位的的经纬度(国外)都是基于WGS-84坐标系的;可是在国内是不容许直接用WGS84坐标系标注的,必须通过加密后才能使用;html

2.GCJ-02坐标系,又名“火星坐标系”,是我国国测局首创的坐标体系,由WGS-84加密而成,在国内,必须至少使用GCJ-02坐标系,或者使用在GCJ-02加密后再进行加密的坐标系,如百度坐标系。高德和Google在国内都是使用GCJ-02坐标系,能够说,GCJ-02是国内最普遍使用的坐标系;java

3.百度坐标系:bd-09,百度坐标系是在GCJ-02坐标系的基础上再次加密偏移后造成的坐标系,只适用于百度地图。(目前百度API提供了从其它坐标系转换为百度坐标系的API,但却没有从百度坐标系转为其余坐标系的API)ios

2、为何会发生偏移?

1.因为坐标系之间不兼容,如在百度地图上定位的经纬度拿到高德地图上直接描点就确定会发生偏移;只考虑国内的状况,高德地图和Google地图是能够不通过转换也可以准确显示的(在国内用的都是GCJ-02坐标系);下面是收录了网上的WGS-84,GCJ-02,百度坐标系(bd-09)之间的相互转换的方法,经测试,是转换后相对准确可用的。git

3、代码

Java:github

package com.zehin.map.util; public class GPSUtil { public static double pi = 3.1415926535897932384626; public static double x_pi = 3.14159265358979324 * 3000.0 / 180.0; public static double a = 6378245.0; public static double ee = 0.00669342162296594323; public static double transformLat(double x, double y) { double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x)); ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0; ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0; ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0; return ret; } public static double transformLon(double x, double y) { double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x)); ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0; ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0; ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0; return ret; } public static double[] transform(double lat, double lon) { if (outOfChina(lat, lon)) { return new double[]{lat,lon}; } double dLat = transformLat(lon - 105.0, lat - 35.0); double dLon = transformLon(lon - 105.0, lat - 35.0); double radLat = lat / 180.0 * pi; double magic = Math.sin(radLat); magic = 1 - ee * magic * magic; double sqrtMagic = Math.sqrt(magic); dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); double mgLat = lat + dLat; double mgLon = lon + dLon; return new double[]{mgLat,mgLon}; } public static boolean outOfChina(double lat, double lon) { if (lon < 72.004 || lon > 137.8347) return true; if (lat < 0.8293 || lat > 55.8271) return true; return false; } /** * 84 to 火星坐标系 (GCJ-02) World Geodetic System ==> Mars Geodetic System * * @param lat * @param lon * @return */ public static double[] gps84_To_Gcj02(double lat, double lon) { if (outOfChina(lat, lon)) { return new double[]{lat,lon}; } double dLat = transformLat(lon - 105.0, lat - 35.0); double dLon = transformLon(lon - 105.0, lat - 35.0); double radLat = lat / 180.0 * pi; double magic = Math.sin(radLat); magic = 1 - ee * magic * magic; double sqrtMagic = Math.sqrt(magic); dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); double mgLat = lat + dLat; double mgLon = lon + dLon; return new double[]{mgLat, mgLon}; } /** * * 火星坐标系 (GCJ-02) to 84 * * @param lon * @param lat * @return * */ public static double[] gcj02_To_Gps84(double lat, double lon) { double[] gps = transform(lat, lon); double lontitude = lon * 2 - gps[1]; double latitude = lat * 2 - gps[0]; return new double[]{latitude, lontitude}; } /** * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标 * * @param lat * @param lon */ public static double[] gcj02_To_Bd09(double lat, double lon) { double x = lon, y = lat; double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi); double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi); double tempLon = z * Math.cos(theta) + 0.0065; double tempLat = z * Math.sin(theta) + 0.006; double[] gps = {tempLat,tempLon}; return gps; } /** * * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标 * * @param * bd_lat * @param bd_lon * @return */ public static double[] bd09_To_Gcj02(double lat, double lon) { double x = lon - 0.0065, y = lat - 0.006; double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi); double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi); double tempLon = z * Math.cos(theta); double tempLat = z * Math.sin(theta); double[] gps = {tempLat,tempLon}; return gps; } /**将gps84转为bd09 * @param lat * @param lon * @return */ public static double[] gps84_To_bd09(double lat,double lon){ double[] gcj02 = gps84_To_Gcj02(lat,lon); double[] bd09 = gcj02_To_Bd09(gcj02[0],gcj02[1]); return bd09; } public static double[] bd09_To_gps84(double lat,double lon){ double[] gcj02 = bd09_To_Gcj02(lat, lon); double[] gps84 = gcj02_To_Gps84(gcj02[0], gcj02[1]); //保留小数点后六位 gps84[0] = retain6(gps84[0]); gps84[1] = retain6(gps84[1]); return gps84; } /**保留小数点后六位 * @param num * @return */ private static double retain6(double num){ String result = String .format("%.6f", num); return Double.valueOf(result); } }

c#:web

public class GpsUtil { public static double pi = 3.1415926535897932384626; public static double x_pi = 3.14159265358979324 * 3000.0 / 180.0; public static double a = 6378245.0; public static double ee = 0.00669342162296594323; public static double TransformLat(double x, double y) { double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.Sqrt(Math.Abs(x)); ret += (20.0 * Math.Sin(6.0 * x * pi) + 20.0 * Math.Sin(2.0 * x * pi)) * 2.0 / 3.0; ret += (20.0 * Math.Sin(y * pi) + 40.0 * Math.Sin(y / 3.0 * pi)) * 2.0 / 3.0; ret += (160.0 * Math.Sin(y / 12.0 * pi) + 320 * Math.Sin(y * pi / 30.0)) * 2.0 / 3.0; return ret; } public static double TransformLon(double x, double y) { double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.Sqrt(Math.Abs(x)); ret += (20.0 * Math.Sin(6.0 * x * pi) + 20.0 * Math.Sin(2.0 * x * pi)) * 2.0 / 3.0; ret += (20.0 * Math.Sin(x * pi) + 40.0 * Math.Sin(x / 3.0 * pi)) * 2.0 / 3.0; ret += (150.0 * Math.Sin(x / 12.0 * pi) + 300.0 * Math.Sin(x / 30.0 * pi)) * 2.0 / 3.0; return ret; } public static double[] transform(double lat, double lon) { if (OutOfChina(lat, lon)) { return new double[] { lat, lon }; } double dLat = TransformLat(lon - 105.0, lat - 35.0); double dLon = TransformLon(lon - 105.0, lat - 35.0); double radLat = lat / 180.0 * pi; double magic = Math.Sin(radLat); magic = 1 - ee * magic * magic; double SqrtMagic = Math.Sqrt(magic); dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * SqrtMagic) * pi); dLon = (dLon * 180.0) / (a / SqrtMagic * Math.Cos(radLat) * pi); double mgLat = lat + dLat; double mgLon = lon + dLon; return new double[] { mgLat, mgLon }; } public static bool OutOfChina(double lat, double lon) { if (lon < 72.004 || lon > 137.8347) return true; if (lat < 0.8293 || lat > 55.8271) return true; return false; } /** * 84 to 火星坐标系 (GCJ-02) World Geodetic System ==> Mars Geodetic System * * @param lat * @param lon * @return */ public static double[] Gps84ToGcj02(double lat, double lon) { if (OutOfChina(lat, lon)) { return new double[] { lat, lon }; } double dLat = TransformLat(lon - 105.0, lat - 35.0); double dLon = TransformLon(lon - 105.0, lat - 35.0); double radLat = lat / 180.0 * pi; double magic = Math.Sin(radLat); magic = 1 - ee * magic * magic; double SqrtMagic = Math.Sqrt(magic); dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * SqrtMagic) * pi); dLon = (dLon * 180.0) / (a / SqrtMagic * Math.Cos(radLat) * pi); double mgLat = lat + dLat; double mgLon = lon + dLon; return new double[] { mgLat, mgLon }; } /** * * 火星坐标系 (GCJ-02) to 84 * * @param lon * @param lat * @return * */ public static double[] Gcj02ToGps84(double lat, double lon) { double[] gps = transform(lat, lon); double lontitude = lon * 2 - gps[1]; double latitude = lat * 2 - gps[0]; return new double[] { latitude, lontitude }; } /// <summary> /// 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标 /// 高德谷歌转为百度 /// </summary> /// <param name="lat"></param> /// <param name="lon"></param> /// <returns></returns> public static double[] Gcj02ToBd09(double lat, double lon) { double x = lon, y = lat; double z = Math.Sqrt(x * x + y * y) + 0.00002 * Math.Sin(y * x_pi); double theta = Math.Atan2(y, x) + 0.000003 * Math.Cos(x * x_pi); double tempLon = z * Math.Cos(theta) + 0.0065; double tempLat = z * Math.Sin(theta) + 0.006; double[] gps = { tempLat, tempLon }; return gps; } /// <summary> /// 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标 /// 百度坐标转为高德谷歌坐标 /// </summary> /// <param name="lat"></param> /// <param name="lon"></param> /// <returns></returns> public static double[] Bd09ToGcj02(double lat, double lon) { double x = lon - 0.0065, y = lat - 0.006; double z = Math.Sqrt(x * x + y * y) - 0.00002 * Math.Sin(y * x_pi); double theta = Math.Atan2(y, x) - 0.000003 * Math.Cos(x * x_pi); double tempLon = z * Math.Cos(theta); double tempLat = z * Math.Sin(theta); double[] gps = { tempLat, tempLon }; return gps; } /// <summary> /// gps84转为bd09 /// GPS坐标转为百度坐标 /// </summary> /// <param name="lat"></param> /// <param name="lon"></param> /// <returns></returns> public static double[] Gps84ToBd09(double lat, double lon) { double[] gcj02 = Gps84ToGcj02(lat, lon); double[] bd09 = Gcj02ToBd09(gcj02[0], gcj02[1]); return bd09; } /// <summary> /// 百度坐标转成GPS坐标 /// </summary> /// <param name="lat"></param> /// <param name="lon"></param> /// <returns></returns> public static double[] Bd09ToGps84(double lat, double lon) { double[] gcj02 = Bd09ToGcj02(lat, lon); double[] gps84 = Gcj02ToGps84(gcj02[0], gcj02[1]); //保留小数点后六位 gps84[0] = Retain6(gps84[0]); gps84[1] = Retain6(gps84[1]); return gps84; } /// <summary> /// 保留小数点后六位 /// </summary> /// <param name="num"></param> /// <returns></returns> private static double Retain6(double num) { String result = String.Format("%.6f", num); return Double.Parse(result); } }

 

做者:青檬可乐_ 
连接:https://www.jianshu.com/p/d3dd4149bb0b 算法

 

 

四种Sandcastle方法生成c#.net帮助类帮助文档

 

 方法1、Visual Studio新建documentation生成帮助文档

        前段时间在网上收集和本身平时工做总结整理了《干货,比较全面的c#.net公共帮助类》,整理完成上传github以后我又想,既然是帮助类,总得有个帮助文档因而乎想到了Sandcastle,Sandcastle是微软官方生成帮助文档这发面的工具。sql

       它能够配合Microsoft Visual Studio生成的dll和xml注释文件生成完整的帮助文档。数据库

       结合可视化工具Sandcastle Help File Builder,简单直接,还能生成各类属性的说明。c#

       支持Helpe1x:chm, Helper2x:Hxs, Website,HelperView等多种格式并且扩展灵活功能强大,下面咱们就看一下怎样用Sandcastle生成chm文档。

   1、下载

     首先咱们前往CodePlex下载Sandcastle,地址:http://sandcastle.codeplex.com/

     而后下载Sandcastle Help File Builder,地址:http://shfb.codeplex.com/,点击右边download下载便可。

2、安装

      Sandcastle,直接Next就能够了,Sandcastle Help File Builder要说一下的是,在MAML Schema IntelliSense for Visual Studio为vs安装插件的时候必定要勾选上,否则新建项目的时候会没有这个选项。

3、设置

    在生成这里设置xml文档文件,保存,编译以后在你项目目录的bin\Debug就会看到生成的xml文件了。

4、新建项目documentation

    首先 新建documentation项目,这里就是安装Sandcastle Help File Builder的时候勾选上vs的缘由。若是没有勾选上,这里新建的时候没有这个选项的。

    

 而后勾选上你刚才已经生成的dll和xml文件,右键属性如上图写上标题。编译生成便可。这里有一点要注意,可能会报错(SHFB: Error BE0037: Could not find the path the the HTML Help 1 compiler. See the error number topic in the help file for details.),是没有安装Microsoft HTML Help,固然你安装了以后能够跳过此步骤。

若是没有安装Microsoft HTML Help,咱们到https://www.microsoft.com/en-us/download/details.aspx?id=21138去下载Microsoft HTML Help而后安装。

5、生成

若是没有报错,直接生成,而后咱们项目目录的Help就能够看到生成的帮助文档了

     是否是很简单。这样咱们就生成了以前帮助类的帮助文档了。另外我再介绍几种生成帮助文档的方式。

方法2、cmd生成帮助文档

在Sandcastle和Sandcastle Help File Builder都安装好的前提下,

在咱们将步骤三生成的Common.Utility.dll 和Common.Utility.xml 拷贝至C:\Program Files (x86)\Sandcastle\Examples\Sandcastle(Sandcastle安装路径)下面。

这种方法是一种批处理的方法,而后咱们打开cmd,输入build_sandcastle.bat vs2005 Common.Utility 回车,而后进行批处理。

咱们会看到这目录下生成不少文件夹,若是过程没有报错,咱们在chm 文件夹就会看到咱们生成的帮助文档了。

方法3、SandcastleBuilderGUI

咱们根据上面的设置,而后引入Common.Utility.dll 和Common.Utility.xml,生成便可。相关设置参考:http://www.cnblogs.com/lonely7345/archive/2010/01/13/1647245.html

方法4、Sandcastle Help File Builder可视化工具

经过Sandcastle的图形操做界面。在C:\Program Files (x86)\Sandcastle\Examples\Generic\SandcastleGui.exe下打开以下界面。

根据图上相关设置而后点击Build按钮。便可生成帮助文档,是否是更方便简洁。

固然前提是也是生成Common.Utility.dll 和Common.Utility.xml的状况下面。

如上四种方法生成帮助文档。至此c#.net帮助类告一段落。

 

本文来自:http://www.cnblogs.com/anyushengcms/p/7682501.html

 

 

 

文档API生成神器SandCastle使用心得

 

1、功能描述

  关于Sandcastle网上的参考资料相对较少,Google出来不少资料都是全英文的,相对于我这种英语渣渣看起来仍是很费劲的。

  言简意赅,Sandcastle主要功能是可以将C#类生成相似MSDN风格帮助文档的工具,支持本地化,并提供一个基本的命令行编译器界面和一个Visual Studio插件。
优势:

  1.生成简单,工做量小,几分钟以内就能完成一个项目的api文档制做。
  2.自动生成索引项、内容项目表、主题块和页面布局,提升一致性和熟悉程度。
  3.代码高亮,易读性强
  4.生成api界面美观。
缺点:

  只支持visual studio,意思是只支持微软旗下产品。

2、下载与安装

  我是在github中下载的sandcastle,连接隧道 https://github.com/EWSoftware/SHFB/releases,下载时需注意版本号,我没有看版本备注就直接下载了最新版本的sandcastle,安装后生成api后直接报错了,不能生成成功。后来排查后发现是版本问题,个人idea是vs2013,当前sandcastle版本只支持最低vs2015的Idea,因此一直报错。

这个版本中备注描述的很清楚,这是最后一个支持vs2013的版本。

3、配置SandCastle

  主要配置详解

3.1 首先打开SandCastle,新建一个文件用来存放sandcastle新建的工程文件,相似vs中新建项目后的解决方案。

3.2 在项目属性中选择须要生成的api类型,若是你想生成相似MSDN帮助文档风格,就能够选择Website。

3.3 Framework version 选择生成解决方案的framework版本号,若是与之不一致,则生成api时会报错

  chm类型生成的文档(参考)

   website类型

  在vs中的引用类按f1可打开该类的帮助文档。

3.4.点击Project Explorer,点击新建的api文件,右击Documentation Sources选择Add Document Source

  

3.5 选择的类库生成属性中需在输出中xml文档文件复选框打钩在生成,不然生成api无效。

3.6 选择所需生成的类库,也就是后缀名为.csproj的文件便可

4、常见错误

4.1 SHFB: Error BE0043: Unexpected error detected in last build step.  See output above for details.

  错误信息的意思是缺乏程序集的引用,那我就须要把不用的程序集剔除掉,那么如何剔除呢,请看一下操做

  

  

4.2 SHFB: Error BE0064: BUILD CANCELLED BY USER

  这个错误是因为框架版本不一致所引发的,也就是若是该项目生成时选择的framework版本为4.5,而sandcastle配置的是4.0版本,那么就会报错。

4.3 Sandcastle [丢失<summary> 节点]的问题

  遇到这个问题,首先查看代码注释是否有<summary>节点,是否规范。

  

  而后有人会说我明明在代码中已经定义了summary 节点,为何还会报这种错呢?

  这种我尝试最暴力的方法就是让它不提示这个错误,在sandcastle中设置missing tags,取消<summary> elments 的报错信息,点击取消复选框,哪一个节点的报错就不会报错。

  

5、SandCastle在vs中的使用

  前面说了都是sandcastle软件的独立使用,还有一种方法是将其集成在vs中使用,使用方法与独立使用相差不大。

       若是是已经安装了sandcastle,那么请忽略如下安装步骤。

       5.1 在sandcastle目录文件夹下找到后缀为vsix的插件,双击执行,若是弹出此扩展已安装,那么表示安装成功

  

5.2 在需生成api的项目下添加项目,若是已安装成功,那么在已安装的扩展插件中Documentation就会出现sandcastle插件,输入名称,存放位置,点击肯定添加。

  

  5.3.添加完成后,此时的操做和不是集成在vs中的无明显差异,如需生成文档,右击新建的文件,点击生成便可。

  

6、运行生成API

  上面全部步骤完成以后就能够运行sandcastle了,点击build the help file生成

  

  生成成功以后在当前生成目录下,查看生成文件是否齐全,若是文件不全,那么缘由在于生成不成功或配置不正确

  

  双击index.html查看api中是否有报错信息,代码是否高亮,连接是否可点。

 

 

 

 

 

最近才开始学习ASP.NET Core,发现社区的学习资料不少,可是相关的视频教程不是不少,52ABP官方有两个视频教程,可是ABP框架比较臃肿,初学者学起来有点吃力,因此仍是推荐你们先啃书或者官方文档,有点基础知识了再看视频教程学习,我的以为这样学起来比较好一点。通过一段时间的学习后我找到一些相关的免费视频教程,发现仍是不错,推荐给你们,共同窗习,共同进步!

一,文档教程汇总:

.NET官方在线文档 

ASP.NET Core官方中文离线教程

EF Core官方中文离线教程

零度教程(零度网站上面有不少免费博客和视频教程)

大内老A专栏

 

二,视频教程汇总:

说明:我比较喜欢在B站上看视频教程,别人都是在上面追番,我却喜欢在上面看一些教程,这是我全部的B站教程收藏夹,由于上面有不少其余地方要收费教程和一些YouTube上搬运的视频,并且还没广告,固然也有很多原创的UP主,我比较喜欢的是Anduin2017 ,他录制了不少不错视频教程,推荐你们去看一下。这是我在B站正在学习或者学过的.NET Core视频教程的收藏夹。你们不嫌麻烦也能够关注一下我,我后面也打算在上面作一些技术视频教程。固然网上还有一些不错的收费视频教程,做为学生党的我也没有这个余钱去买,一是比较贵,二是我也以为不必,把下面这个教程多看几遍,而后动手实践一下,再多啃几本书和浏览一些博客就够了。

1,NewsPublish项目 — 在线视频地址,这个新闻发布系统主要由Asp.Net Core&Sql Server数据库搭建,比较适合初学者,若是你们以为Sql Server 2017客户端比较大,吃内存的话,推荐你们用微软的Azure Data Studio ,这个Sql Server的GUI比较轻量级,界面也很友好,固然功能确定也没有Sql Server 2017那么多,不过通常对于我来讲够用了。

另外推荐两个有用的网站:

2,草根专栏的教程 — ASP.NET Core 2.1 + Ng6实战GraphQL in ASP.NET Core 后面这个视频教程也不太适合初学者,至少的有ASP.NET Core Web API相关的基础知识才行,先看第一个视频教程吧,结合做者的博客一块儿学习。

3,52ABP的视频教程 —ASP.NET Core 2.X ABP框架入门教程Asp.NET Core2.0 EF Core 项目实战入门视频教程,做者将ABP框架用ASP.NET Core实现的,里面涉及的知识面比较广,能够结合52ABP的官方文档学习,第一个教程以 .NET Core + Entity Framework Core为基础,中间涉及到各类插件和组件如: AutoMapper、CodeFirst、IOC,仓储、MVC和EF,比较适合初学者。后面这个视频是收费的教程,不过也不贵,才35元,确定要支持做者。

4,首届.NET Core开源峰会演讲 — 这个虽然不是作.NET Core项目教程,可是这个dnc开源峰会目前是由社区驱动的最高.NET Core在线开源会议,确定是要去了解一下的,这里是官网Github,B站dncto视频地址 ,第二届会议将会在2018年12月30召开,固然若是你是.NET Core开发大牛,也能够参加讲师报名。

 

三,项目案例汇总:

一系列使人敬畏的.NET核心库,工具,框架和软件

Github上的一个开源项目,目标是创建一个由知名资源组成的分类社区驱动集合。

 

 

 Coding The World!

 

https://www.cnblogs.com/ckjbug/archive/2018/10/09/9763503.html

相关文章
相关标签/搜索