Java学习路线一

Java路线参考:

Spring Boot

  1. SpringBoot介绍
  2. SpringBoot的核心功能
  3. SpringBoot的优势
  4. SpringBoot入门程序
  5. 起步依赖原理分析
  6. 自动配置原理解析
  7. 自定义起步依赖并实现自动配置
  8. SpringBoot配置文件类型
  9. 配置文件与配置类的属性映射方式
  10. SpringBoot整合Mybatis
  11. SpringBoot整合Junit
  12. SpringBoot整合HikariCP
  13. SpringBoot整合Redis

Spring Cloud

  1. 架构的演进过程介绍
  2. SpringCloud介绍和Dubbo对比
  3. 服务注册中心Eureka介绍
  4. Eureka服务端开发
  5. 微服务开发并注册到Eureka服务注册中心
  6. Eureka保护模式介绍
  7. 客户端负载和服务端负载的介绍
  8. Ribbon实现客户端负载均衡
  9. Feign的介绍和实现
  10. Feign工作原理和注意事项
  11. 雪崩效应与熔断器介绍
  12. 熔断器Hystrix使用
  13. 网关介绍
  14. 基于Gateway构建网关服务
  15. 通过Gateway网关访问微服务
  16. Spring Cloud Config介绍
  17. 使用Git存储的方式实现配置管理
  18. 微服务改造从配置中心获取配置信息
  19. 服务总线Spring Cloud Bus介绍和应用

Elasticsearch

  1. ElasticSearch简介
  2. ElasticSearch安装与启动
  3. Elasticsearch核心概念、操作入门
  4. ElasticSearch集成IK分词器
  5. ElasticSearch常用编程操作
  6. ElasticSearch中的DSL搜索
  7. ElasticSearch集群环境搭建和介绍
  8. 8.ElasticSearch关键字搜索
  9. ElasticSearch多条件过滤
  10. Spring Data ElasticSearch使用

RabbitMQ

  1. RabbitMQ的介绍
  2. AMQP和JMS介绍
  3. RabbitMQ的工作原理
  4. RabbitMQ入门案例
  5. Work Queues 工作队列模式
  6. Publish/Subscribe 发布订阅模式
  7. Routing 路由模式
  8. Topics 通配符模式
  9. Spring-AMPQ的搭建
  10. Spring-AMPQ生产者创建
  11. Spring-AMPQ消费者创建

Node.js&ES

  1. Node.js的作用
  2. Node.js下载和安装
  3. Node.js快速入门
  4. 创建前端工程
  5. 前端工程中函数的使用
  6. 模块化编程
  7. 创建前端Web服务器
  8. NPM的作用和说明
  9. NPM的本地安装与全局安装
  10. NPM镜像切换
  11. Webpack的介绍和作用
  12. Webpack前端资源打包
  13. ECMAScript介绍和发展历程
  14. ES6变量声明let和const
  15. ES6模板字符串和对象声明简化
  16. ES6对象和数字的使用
  17. Promise对象的使用
  18. Export和Import的使用

Docker

  1. Docker简介
  2. 容器与虚拟机比较
  3. Docker的安装和启动
  4. Docker镜像命令介绍和应用
  5. Docker容器命令介绍和应用
  6. Docker部署Mysql
  7. Docker部署Tomcat
  8. Docker部署Nginx
  9. Docker部署Redis
  10. 容器保存转为镜像
  11. 镜像备份
  12. 镜像恢复和迁移
  13. Dockerfile介绍和常用指令
  14. Docker Compose 常用命令
  15. Docker私有仓库使用.
发表在 java | Java学习路线一已关闭评论

RabbitMQ 命令备忘

rabbitmqctl list_queues:查看所有队列信息

rabbitmqctl stop_app:关闭应用(关闭当前启动的节点)

rabbitmqctl start_app:启动应用,和上述关闭命令配合使用,达到清空队列的目的

rabbitmqctl reset:从管理数据库中移除所有数据,例如配置过的用户和虚拟宿主, 删除所有持久化的消息(这个命令要在rabbitmqctl stop_app之后使用)

rabbitmqctl force_reset:作用和rabbitmqctl reset一样,区别是无条件重置节点,不管当前管理数据库状态以及集群的配置。如果数据库或者集群配置发生错误才使用这个最后的手段

rabbitmqctl status:节点状态

rabbitmqctl add_user username password:添加用户

rabbitmqctl list_users:列出所有用户

rabbitmqctl list_user_permissions username:列出用户权限

rabbitmqctl change_password username newpassword:修改密码

rabbitmqctl add_vhost vhostpath:创建虚拟主机

rabbitmqctl list_vhosts:列出所有虚拟主机

rabbitmqctl set_permissions -p vhostpath username ".*" ".*" ".*":设置用户权限

rabbitmqctl list_permissions -p vhostpath:列出虚拟主机上的所有权限

rabbitmqctl clear_permissions -p vhostpath username:清除用户权限

rabbitmqctl -p vhostpath purge_queue blue:清除队列里的消息

rabbitmqctl delete_user username:删除用户

rabbitmqctl delete_vhost vhostpath:删除虚拟主机

 

.

发表在 mq | RabbitMQ 命令备忘已关闭评论

HTTP PUT and POST

POST 方法用来传输实体的主体,PUT方法用来传输文件。

两个方法都是将一个资源附加到服务器端的请求。一些狭窄的意见认为,POST方法用来创建资源,而PUT方法则用来更新资源。这个说法本身没有问题,但是并没有从根本上解释了二者的区别。事实上,它们最根本的区别就是:POST方法不是幂等的,而PUT方法则有幂等性。

幂等(idempotent、idempotence)是一个抽象代数的概念。在计算机中,可以这么理解,一个幂等操作的特点就是其任意多次执行所产生的影响均与依次一次执行的影响相同。

POST在请求的时候,服务器会每次都创建一个文件,但是在PUT方法的时候只是简单地更新,而不是去重新创建。因此PUT是幂等的。

举例,有一个博客系统提供一个Web API,模式是这样http://example.com/blogs/post/{blog-name},很简单,将{blog-name}替换为我们的blog名字,往这个URI发送一个HTTP PUT或者POST请求,HTTP的body部分就是博文,这是一个很简单的REST API例子。

用PUT方法还是POST方法?取决于这个REST服务的行为是否是idempotent的,假如我们发送两个http://example.com/blogs/post/Sample请求,服务器端是什么样的行为?如果产生了两个博客帖子,那就说明这个服务不是idempotent的,因为多次使用产生了副作用了嘛;如果后一个请求把第一个请求覆盖掉了,那这个服务就是idempotent的。前一种情况,应该使用POST方法,后一种情况,应该使用PUT方法。

如果用PUT来达到更改资源,每次请求需要client提交资源全部信息,如果只有部分信息,不应该使用PUT(因为服务器使用client提交的对象整体替换服务器的资源)。

POST不同于一般的增删改,使用场景比较多。根据RFC文档上描述,有以下几个场景:(tools.ietf.org/html/rfc

- Annotation of existing resources;

- Posting a message to a bulletin board, newsgroup, mailing list, or   
  similar group of articles;

- Providing a block of data, such as the result of submitting a
  form, to a data-handling process;

- Extending a database through an append operation.

服务器在实现POST是不可预知,所以将其定义为不安全、不幂等的Verb。基本上不能简单的归纳为“增删改”之类的行为,都可以使用POST方法。

 

 

发表在 technologys | HTTP PUT and POST已关闭评论

CURD( Create Update Read Delete ) RESTful proposal

 

Operation   SQL     HTTP    
Create      INSERT  POST    
Read        SELECT  GET 
Update      UPDATE  PUT 
Delete      DELETE  DELETE  

Reference:

HTTP PUT and POST

 

.

 

发表在 technologys | CURD( Create Update Read Delete ) RESTful proposal已关闭评论

WebMvcConfig

.



import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;


@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    private final Logger logger = LoggerFactory.getLogger(WebMvcConfig.class);

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST","OPTIONS")
                .allowedHeaders("*")
                .exposedHeaders("Access-Control-Allow-Headers",
                        "Access-Control-Allow-Methods",
                        "Access-Control-Allow-Origin",
                        "Access-Control-Max-Age",
                        "X-Frame-Options")
                .allowCredentials(false)
                .maxAge(3600);
    }

    
    /**
     * The bean shown in the preceding example registers any @ServerEndpoint
     * annotated beans with the underlying WebSocket container. When deployed to a
     * standalone servlet container, this role is performed by a servlet container
     * initializer, and the ServerEndpointExporter bean is not required.
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
    
}

 

.

发表在 java | WebMvcConfig已关闭评论

WordPress manual upgrade

 

1、备份Wordpress资料及数据库。

2、下载新版的Wordpress。

3、删除主机上的wp-includes和wp-admin目录。

4、把解压在本地电脑的 WordPress 文件夹中除了wp-content目录外的所有文件都上传并覆盖到你博客主机相对应的位置。遇到是否覆盖时,选择全部覆盖就是了。

5、运行 http://你的地址/wp-admin/upgrade.php,执行升级。

 

.

发表在 technologys | WordPress manual upgrade已关闭评论

ssh-agent / git 指定特定 key

使用代理封装指定行定KEY


#add 1.
ssh-agent bash -c 'ssh-add /somewhere/yourkey; git clone git@github.com:user/project.git'

#or 2.
ssh-agent $(ssh-add /somewhere/yourkey; git clone git@github.com:user/project.git)

 

References:

https://blog.csdn.net/zhouguoqionghai/article/details/92134462

https://zhuanlan.zhihu.com/p/126117538

.

发表在 linux | ssh-agent / git 指定特定 key已关闭评论

SpringBoot CorsConfig

案例一:


package com.wang.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1
        corsConfiguration.addAllowedHeader("*"); // 2
        corsConfiguration.addAllowedMethod("*"); // 3
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); // 4
        return new CorsFilter(source);
    }


}

 

案例二:


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class GlobalCorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        //1.添加CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        //1) 允许的域,不要写*,否则cookie就无法使用了
        config.addAllowedOrigin("http://www.example.com");
        //2) 是否发送Cookie信息
        config.setAllowCredentials(true);
        //3) 允许的请求方式
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");
        // 4)允许的头信息
        config.addAllowedHeader("*");

        //2.映射路径,拦截一切请求
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);

        //3.返回新的CorsFilter.
        return new CorsFilter(configSource);
    }
}

 

 


 

 

发表在 java | SpringBoot CorsConfig已关闭评论

CentOS 7 upgrade to CentOS 8

第1步:安装EPEL储存库

首先,通过运行以下命令安装EPL存储库:

yum install epel-release -y

第2步:安装yum-utils工具

成功安装EPEL之后 ,通过运行以下命令来安装yum-utils 。

yum install yum-utils

在CentOS 7中安装yum-utils
此后,您需要通过执行命令来解析RPM软件包。

# yum install rpmconf
# rpmconf -a

保留默认RPM设置
接下来,清理所有不需要的软件包。

# package-cleanup --leaves
# package-cleanup --orphans

干净的RPM软件包
第3步:在CentOS 7中安装dnf
现在安装dnf软件包管理器 ,它是CentOS 8的默认软件包管理器。

# yum install dnf

在CentOS 7中安装dnf
您还需要使用以下命令删除yum软件包管理器 。

# dnf -y remove yum yum-metadata-parser
# rm -Rf /etc/yum

在CentOS 7中删除Yum
第4步:将CentOS 7升级到CentOS 8
现在,我们准备将CentOS 7升级到CentOS 8,但在此之前,请使用新安装的dnf软件包管理器升级系统。

# dnf upgrade

升级CentOS 7

接下来,如下所示使用dnf安装CentOS 8发行包。 这需要一段时间。

dnf -y upgrade http://mirrors.163.com/centos/8.0.1905/BaseOS/x86_64/os/Packages/centos-release-8.0-0.1905.0.9.el8.x86_64.rpm

安装CentOS 8版本
接下来,升级EPEL存储库。

dnf -y upgrade https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

升级EPEL存储库
成功升级EPEL存储库后,请删除所有临时文件。

# dnf clean all

删除 CentOS 7 的旧内核 。

# rpm -e `rpm -q kernel`

接下来,请确保删除有冲突的软件包。

# rpm -e --nodeps sysvinit-tools

之后,如图所示启动CentOS 8系统升级。

# dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync

CentOS 8系统升级
第5步:安装适用于CentOS 8的新内核
要为CentOS 8安装新的内核,请运行命令。

# dnf -y install kernel-core

在CentOS 8中安装内核
最后,安装CentOS 8最小软件包。

# dnf -y groupupdate "Core" "Minimal Install"

现在,您可以通过运行检查安装的CentOS版本。

# cat /etc/redhat-release

检查CentOS版本

 

参考:
https://www.howtoing.com/upgrade-centos-7-to-centos-8

 

 

#!/bin/bash

echo 'CentOS 7 upgrade to CentOS 8'

echo '第1步:安装EPEL储存库'
yum update -y
yum remove epel-release mariadb mariadb-connector-c-config redhat-rpm-config -y
#yum install epel-release -y
yum install -y http://mirrors.ustc.edu.cn/epel/epel-release-latest-7.noarch.rpm

echo '第2步:安装yum-utils工具'
yum install yum-utils -y

echo '在CentOS 7中安装yum-utils'
yum install rpmconf -y
rpmconf -a

echo '保留默认RPM设置,接下来,清理所有不需要的软件包'
package-cleanup --leaves
package-cleanup --orphans

# yum remove -y libsysfs-2.1.0-16.el7.x86_64 chefdk-4.6.35-1.el7.x86_64

echo '第3步:在CentOS 7中安装dnf'
yum install dnf -y

echo '在CentOS 7中安装dnf, 您还需要使用以下命令删除yum软件包管理器 。'
dnf -y remove yum yum-metadata-parser
rm -Rf /etc/yum


echo '第4步:将CentOS 7升级到CentOS 8'
dnf -y upgrade
dnf -y install http://mirrors.aliyun.com/centos/8/BaseOS/x86_64/os/Packages/centos-linux-repos-8-2.el8.noarch.rpm http://mirrors.aliyun.com/centos/8/BaseOS/x86_64/os/Packages/centos-linux-release-8.3-1.2011.el8.noarch.rpm http://mirrors.aliyun.com/centos/8/BaseOS/x86_64/os/Packages/centos-gpg-keys-8-2.el8.noarch.rpm
dnf -y upgrade http://mirrors.ustc.edu.cn/epel/epel-release-latest-8.noarch.rpm

# dnf -y install http://mirrors.aliyun.com/centos/8/BaseOS/x86_64/os/Packages/centos-linux-repos-8-2.el8.noarch.rpm
# dnf -y http://mirrors.aliyun.com/centos/8/BaseOS/x86_64/os/Packages/centos-gpg-keys-8-2.el8.noarch.rpm
# dnf -y upgrade http://mirrors.ustc.edu.cn/epel/epel-release-latest-8.noarch.rpm

# dnf -y upgrade http://mirrors.163.com/centos/8.0.1905/BaseOS/x86_64/os/Packages/centos-release-8.0-0.1905.0.9.el8.x86_64.rpm
# dnf -y upgrade https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm


echo '升级EPEL存储库'
dnf clean all
rpm -e `rpm -q kernel`
rpm -e --nodeps sysvinit-tools
dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync


echo '第5步:安装适用于CentOS 8的新内核'
dnf -y install kernel-core


echo '安装CentOS 8最小软件包'
dnf -y groupupdate "Core" "Minimal Install"
cat /etc/redhat-release




 

 

.

 

发表在 linux | CentOS 7 upgrade to CentOS 8已关闭评论

Docker Desktop - WSL 2 从C盘迁移到其他目录

WSL

WSL:适用于 Linux 的 Windows 子系统。

  • 什么是适用于 Linux 的 Windows 子系统?

适用于 Linux 的 Windows 子系统可让开发人员按原样运行 GNU/Linux 环境 - 包括大多数命令行工具、实用工具和应用程序 - 且不会产生虚拟机开销。

  • 什么是 WSL 2?

WSL 2 是适用于 Linux 的 Windows 子系统体系结构的一个新版本,它支持适用于 Linux 的 Windows 子系统在 Windows 上运行 ELF64 Linux 二进制文件。 它的主要目标是提高文件系统性能,以及添加完全的系统调用兼容性。

--

启用WSL后,docker运行数据都在WSL发行版中,文件位置都只能由WSL管理!

安装docker后,docker会自动创建2个发行版:

  • docker-desktop
  • docker-desktop-data

 

WSL发行版迁移

网上查了一下wsl发行版迁移,几乎都是说使用LxRunOffline.exe

经过我试验,LxRunOffline.exe确实可以迁移自己安装的发行版,却迁移不了docker自动创建的2个发行版!

最后只能去github提了个issues:https://github.com/docker/for-win/issues/7348

下面是操作方法:

  1. 首先关闭docker
  2. 关闭所有发行版:
    wsl --shutdown
  3. 将docker-desktop-data导出到D:\SoftwareData\wsl\docker-desktop-data\docker-desktop-data.tar(注意,原有的docker images不会一起导出)
    wsl --export docker-desktop-data D:\SoftwareData\wsl\docker-desktop-data\docker-desktop-data.tar
  4. 注销docker-desktop-data:
    wsl --unregister docker-desktop-data
  5. 重新导入docker-desktop-data到要存放的文件夹:D:\SoftwareData\wsl\docker-desktop-data\:
    wsl --import docker-desktop-data
    D:\SoftwareData\wsl\docker-desktop-data\
    D:\SoftwareData\wsl\docker-desktop-data\docker-desktop-data.tar
    --version 2

--

只需要迁移docker-desktop-data一个发行版就行,另外一个不用管,它占用空间很小。
完成以上操作后,原来的%LOCALAPPDATA%/Docker/wsl/data/ext4.vhdx就迁移到新目录了:

重启docker

参考:
https://docs.microsoft.com/zh-cn/windows/wsl/
https://docs.docker.com/docker-for-windows/wsl/
https://www.cnblogs.com/xhznl/p/13184398.html

 

 

发表在 cloud | Docker Desktop - WSL 2 从C盘迁移到其他目录已关闭评论

apache dubbo / zookeeper / zookeeper not connected

 

dubbo 2.7.3 升级2.7.5 或更高版本时 连接不到zookeeper

方法一:

dubbo.config-center.timeout:10000
dubbo.registry.timeout: 100000

参考:
https://github.com/apache/dubbo-spring-boot-project/issues/668

 

方法二:

换掉dubbo的版本号就好了

如下:

<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.3</version>
</dependency>
<!-- 使用zk 做注册中心,Dubbo 需要的依赖 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<type>pom</type>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>

 

 

.

发表在 java | apache dubbo / zookeeper / zookeeper not connected已关闭评论

linux firewalld

#进程与状态相关
systemctl start firewalld.service #启动防火墙
systemctl stop firewalld.service #停止防火墙
systemctl status firewalld #查看防火墙状态
systemctl enable firewalld #设置防火墙随系统启动
systemctl disable firewalld #禁止防火墙随系统启动
firewall-cmd --state #查看防火墙状态
firewall-cmd --reload #更新防火墙规则
firewall-cmd --list-ports #查看所有打开的端口
firewall-cmd --list-services #查看所有允许的服务
firewall-cmd --get-services #获取所有支持的服务

#区域相关
firewall-cmd --list-all-zones #查看所有区域信息
firewall-cmd --get-active-zones #查看活动区域信息
firewall-cmd --set-default-zone=public #设置public为默认区域
firewall-cmd --get-default-zone #查看默认区域信息

#接口相关
firewall-cmd --zone=public --add-interface=eth0 #将接口eth0加入区域public
firewall-cmd --zone=public --remove-interface=eth0 #从区域public中删除接口eth0
firewall-cmd --zone=default --change-interface=eth0 #修改接口eth0所属区域为default
firewall-cmd --get-zone-of-interface=eth0 #查看接口eth0所属区域

#端口控制
firewall-cmd --query-port=8080/tcp # 查询端口是否开放
firewall-cmd --add-port=8080/tcp --permanent #永久添加8080端口例外(全局)
firewall-cmd --remove-port=8800/tcp --permanent #永久删除8080端口例外(全局)
firewall-cmd --add-port=65001-65010/tcp --permanent #永久增加65001-65010例外(全局)
firewall-cmd --zone=public --add-port=8080/tcp --permanent #永久添加8080端口例外(区域public)
firewall-cmd --zone=public --remove-port=8080/tcp --permanent #永久删除8080端口例外(区域public)
firewall-cmd --zone=public --add-port=65001-65010/tcp --permanent #永久增加65001-65010例外(区域public)

 

.

 

 

发表在 linux | linux firewalld已关闭评论

Mobile White Project

白名单管理项目

.

 

发表在 java | Mobile White Project已关闭评论

树莓派 GPIO 控制 / WEB控制 - 备忘

转载于:
https://www.cnblogs.com/zhenqichai/p/raspberry-pi-control-GPIO-with-python.html

Python 控制树莓派 GPIO 输出:控制 LED 灯

树莓派 GPIO 控制输出的入门应该都是从控制 LED 灯开始的吧。

树莓派版本:Model 3B+

树莓派系统:Raspbian Stretch with desktop and recommended software,April 2019

连接装置

准备一个 LED 灯,两个两头都为母的杜邦线。对照下图连接树莓派和 LED 灯,要求一个是地线(GND)连接灯的负极,一个有 GPIO + BCM 编号连接正极。我选择了 pin 号为 6 和 12 的两个引脚。你也可以选择别的,记得将之后的代码中 BCM 编号修改正确

在断电状态下连接。连接好的如下图,我的 LED 灯有正负极的提示,图中所示红色箭头指向的是正极,蓝色箭头是负极。如果你的 LED 灯是最简单的那种,长引脚就是正极,短的负极。

树莓派开机。

安装 RPI.GPIO

我装的树莓派系统已经满足所需要的环境,不需要额外下载。

你可以测试是否已经有该模块,在终端打开 Python3,然后尝试导入库: import RPi.GPIO as GPIO 。如果没有出现error,就表示已经有了,可以直接跳到下一步。

如果出现错误,则执行以下命令:

sudo apt-get update
sudo apt-get install python3-rpi.gpio

测试 GPIO

按下图所示依次输入命令,观察。

GPIO.setmode() 有两种参数可以选择:可以使用 GPIO.BOARD 选项告诉库根据 GPIO 接口的引脚号引用信号,或者使用 Broadcom 芯片的信号编号( GPIO.setmode(GPIO.BCM) )。

在选择了模式之后,需要确定在程序中使用哪一个 GPIO 信号以及将家门用来作为输入还是输出:GPIO.setup(channel, direction)。我给的例子里是 GPIO.setup(18, GPIO.OUT) 。

后面两个命令控制灯的开关: GPIO.output(18, GPIO.HIGH) 和 GPIO.output(18, GPIO.LOW) 。

GPIO.cleanup() 用于重置 GPIO 接口,它把所有的 GPIO 引脚设置为低电平状态,所以没有多余的信号出现在界面上。在不使用改函数的情况下,如果试图配置一个已分配信号值的 GPIO 信号引脚,那么 RPi.GPIO 模块会产生一条警告信息。

闪烁 LED

然后我在树莓派上编写了下面这个代码让 LED 灯闪烁五次,保存在 Desktop,命名为 led.py。

复制代码
#!/usr/bin/python3

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
GPIO.output(18, GPIO.LOW)
blinks = 0
print('开始闪烁')
while (blinks < 5):
    GPIO.output(18, GPIO.HIGH)
    time.sleep(1.0)
    GPIO.output(18, GPIO.LOW)
    time.sleep(1.0)
    blinks = blinks + 1
GPIO.output(18, GPIO.LOW)
GPIO.cleanup()
print('结束闪烁')
复制代码

 

演示结果:

也可以以通过 PWM 信号来达到让灯闪烁的效果。

#!/usr/bin/python3

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
blink = GPIO.PWM(18, 1)
try:
    blink.start(50)
    while True:
        pass
except KeyboardInterrupt:
    blink.stop()
GPIO.cleanup()

 

start() 方法指定了占空比(从 1 到 100)。在开始 PWM 信号后,程序就可以解放出来做其他事情了。GPIO 18 会持续发送 PWM 信号,直到停止它。 blink = GPIO.PWM(18, 1) 指定了 PWM 信号以 1HZ 的频率发送,灯 1 秒闪烁一次。按 Control + C 中止闪烁。

参考资料

《树莓派Python编程 入门与实战(第2版)》,人民邮电出版社

上述内容转载至:
作者:Zhenqi Chai
出处:https://www.cnblogs.com/zhenqichai/
版权声明:本文为作者原创文章,欢迎转载,但必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

-------------------------------------------------------------------------
树莓派-通过Web控制GPIO针脚输出高低电平(改进版)

1.Tornado简介

Tornado一款使用 Python 编写的,相对简单的 非阻塞式 Web 服务器,它是非阻塞式服务器,而且速度相当快。得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以千计的连接,因此 Tornado 是实时 Web 服务的一个 理想框架。

官方网站:http://www.tornadoweb.cn

官方文档:http://www.tornadoweb.cn/documentation

整个文档就一个网页,把http服务器常用的功能都讲述了一遍,如果有编程基础,应该很快就能上手。

2.Tornado安装

方式1:pip 安装:
sudo pip install tornado

方式2:源代码安装:
wget https://pypi.python.org/packages/source/t/tornado/tornado-4.3.tar.gz
tar xvzf tornado-4.3.tar.gz
cd tornado-4.3
python setup.py build
sudo python setup.py install

 

3.HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>树莓派Web控制中心</title>
    <script src="static/js/jquery-3.2.1.min.js" type="text/javascript"></script>
    <script src="static/js/bootstrap.min.js" type="text/javascript"></script>
    <link href="static/css/bootstrap.css" rel="stylesheet" type="text/css" />
    <link href="static/css/font-awesome-4.7.0/css/font-awesome.min.css" rel="stylesheet"
        type="text/css" />
    <style type="text/css">
        .page-header { margin: 20px 0; border-bottom: 1px solid #eee; padding-bottom: 0; text-align: center; }
        .btn-item { text-align: center; }
        i { margin-right: 3px; display: inline-block; }
        h1 { text-align: center; }
        .tip { font-weight: bold; color: black; }
        .lead { font-size: small; }
        .gpio-item { text-align: center; }
        .btn-gnd, .btn-gpio { padding: 10px 5px; margin-bottom: 5px; width: 100%; font-size: small; }
        .gpio .row { margin-top: 5px; }
    </style>
</head>
<body>
    <div class="container">
        <div class="page-header">
            <h3>
                树莓派Web控制中心</h3>
            <p class="lead">
                用于控制连接到树莓派的各种传感器
            </p>
        </div>
        <div class="panel panel-default">
            <div class="panel-heading">
                设备</div>
            <div class="panel-body">
                <div class="row">
                    <div class="col-xs-3 btn-item">
                    </div>
                    <div class="col-xs-3 btn-item">
                        <a class="btn btn-danger btn-trigger"><i class="fa fa-power-off"></i>关机</a>
                    </div>
                    <div class="col-xs-3 btn-item">
                        <a class="btn btn-primary btn-trigger"><i class="fa fa-refresh"></i>重启</a>
                    </div>
                    <div class="col-xs-3 btn-item">
                    </div>
                    <script type="text/javascript">
                        var url = "/";
                        $(function () { 
                            $(".btn-trigger").click(function () {
                                var text = $(this).text().replace(/ /g, "").replace(/\n/g, "").replace(/\r/g, "").replace(/\t/g, "");
                                var cmd = "";
                                switch (text) {
                                    case "关机":
                                        cmd = "sudo shutdown -h now";
                                        break;
                                    case "重启":
                                        cmd = "sudo reboot";
                                        break;
                                }
                                if (confirm("确定要执行该命令吗?")) {
                                    $.ajax({
                                        type: "POST",
                                        url: url,
                                        data: {
                                            action: "run-shell-cmd",
                                            cmd: cmd
                                        },
                                        success: function (result) {
                                            //$(".tip").html(result);
                                        }
                                    });
                                }
                            });
                        });
                    </script>
                </div>
            </div>
        </div>
        <div class="panel panel-default">
            <div class="panel-heading">
                GPIO (蓝色->低电平,红色->高电平)</div>
            <div class="panel-body gpio">
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        左侧
                    </div>
                    <div class="col-xs-6 gpio-item">
                        右侧
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (9) 左05</button>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (6) 右03</button>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="17">17 (11) 左06</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="18">18 (12) 右06</a>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="27">27 (13) 左07</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (14) 右07</button>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="22">22 (15) 左08</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="23">23 (16) 右08</a>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (25) 左13</button>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="24">24 (18) 右09</a>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="5">05 (29) 左15</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (20) 右10</button>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="6">06 (31) 左16</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="25">25 (22) 右11</a>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="13">13 (33) 左17</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (30) 右15</button>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="19">19 (35) 左18</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="12">12 (32) 右16</a>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="26">26 (37) 左19</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (34) 右17</button>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="20">20 (37) 右19</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="16">16 (36) 右18</a>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (39) 右20</button>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="21">21 (40) 右20</a>
                    </div>
                </div>
                <script type="text/javascript">
                    $(function () {
                        $(".btn-gpio").click(function () {
                            var gpio = $(this).attr("pin");
                            if ($(this).hasClass("btn-danger")) {
                                $(this).removeClass("btn-danger").addClass("btn-primary");
                            } else {
                                $(this).removeClass("btn-primary").addClass("btn-danger");
                            }
                            var status = $(this).hasClass("btn-danger") ? 1 : 0;
                            $.ajax({
                                type: "POST",
                                url: url,
                                data: {
                                    action: "set-gpio-pin",
                                    pin: gpio,
                                    status: status
                                },
                                success: function (result) {
                                    //$(".tip").html(result);
                                }
                            });
 
                        });
                    })
                </script>
            </div>
        </div>
    </div>
</body>
</html>

 

4.Python脚本

 

#coding: utf8
import sys
import RPi.GPIO as GPIO
import time
import os
import tornado.ioloop
import tornado.web
import tornado.httpserver
import tornado.options
from tornado.options import define,options
 
#初始化
def init():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
 
#设置GPIO针脚电平输出
def SetPinStatus(pin,status):
    GPIO.cleanup(int(pin))
    GPIO.setup(int(pin),GPIO.OUT)
    if(int(status)==0):
        GPIO.output(int(pin),GPIO.LOW)
    else:
        GPIO.output(int(pin),GPIO.HIGH)
    
#路由处理	
class IndexHandler(tornado.web.RequestHandler):
        def get(self):
                self.render("index.html")
        def post(self):
                init()
		action=self.get_argument('action')
		#设置GPIO针脚电平输出
		if(action=="set-gpio-pin"):
		    pin = self.get_argument('pin')
                    status = self.get_argument('status')
		    SetPinStatus(pin,status)
		    self.write("true")
		#执行shell脚本,如:关机,重启
		elif(action=="run-shell-cmd"): 
		    cmd = self.get_argument('cmd')
                    os.system(cmd)					
                
if __name__ == '__main__':
    #控制台输出响应结果,正式环境可以不开启
    #tornado.options.parse_command_line()
    settings={
        "static_path":os.path.join(os.path.dirname(__file__),"static")
        }
    app = tornado.web.Application(
        handlers=[
            (r"/",IndexHandler),
            (r"(apple-touch-icon\.png)",tornado.web.StaticFileHandler,dict(path=settings['static_path']))
        ],**settings)
    
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(8020)
    tornado.ioloop.IOLoop.instance().start()
    GPIO.cleanup()


5.示例

上述内容转载于:
https://blog.csdn.net/a497785609/article/details/78060029
6.案例脚本
#coding: utf8

import sys
import RPi.GPIO as GPIO
import time
import os


# RuntimeError: Please set pin numbering mode using GPIO.setmode(GPIO.BOARD) or GPIO.setmode(GPIO.BCM)
GPIO.setmode(GPIO.BCM)
GPIO.setup(19,GPIO.OUT)
GPIO.output(19,GPIO.HIGH)
# GPIO.output(19,GPIO.LOW)

GPIO.setup(26,GPIO.OUT)
GPIO.output(26,GPIO.HIGH)
# GPIO.output(26,GPIO.LOW)
# GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)

 

...
发表在 python | 树莓派 GPIO 控制 / WEB控制 - 备忘已关闭评论

地图坐标系的转换(WGS-84、GCJ-02、BD-09)

C#地图坐标系的转换(WGS-84、GCJ-02、BD-09)

public class GPSChange
    {
        private const double pi = 3.14159265358979324;
        private const double x_pi = 3.14159265358979324 * 3000.0 / 180.0;

        //克拉索天斯基椭球体参数值
        private const double a = 6378245.0;
        //第一偏心率
        private const double ee = 0.00669342162296594323;


        /// <summary>
        /// GCJ-02转换BD-09
        /// </summary>
        /// <param name="gg_lat">纬度</param>
        /// <param name="gg_lon">经度</param>
        /// <returns></returns>
        public static GPSPoint GCJ02_to_BD09(double gg_lat, double gg_lon)
        {
            GPSPoint point = new GPSPoint();
            double x = gg_lon, y = gg_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 bd_lon = z * Math.Cos(theta) + 0.0065;
            double bd_lat = z * Math.Sin(theta) + 0.006;
            point.SetLat(bd_lat);
            point.SetLng(bd_lon);
            return point;
        }

        /// <summary>
        /// BD-09转换GCJ-02
        /// </summary>
        /// <param name="bd_lat">纬度</param>
        /// <param name="bd_lon">经度</param>
        /// <returns></returns>
        public static GPSPoint BD09_to_GCJ02(double bd_lat, double bd_lon)
        {
            GPSPoint point = new GPSPoint();
            double x = bd_lon - 0.0065, y = bd_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 gg_lon = z * Math.Cos(theta);
            double gg_lat = z * Math.Sin(theta);
            point.SetLat(gg_lat);
            point.SetLng(gg_lon);
            return point;
        }



        /// <summary>
        /// WGS-84转换GCJ-02
        /// </summary>
        /// <param name="wgLat">纬度</param>
        /// <param name="wgLon">经度</param>
        /// <returns></returns>
        public static GPSPoint WGS84_to_GCJ02(double wgLat, double wgLon)
        {
            GPSPoint point = new GPSPoint();
            if (OutOfChina(wgLat, wgLon))
            {
                point.SetLat(wgLat);
                point.SetLng(wgLon);
                return point;
            }
            double dLat = TransformLat(wgLon - 105.0, wgLat - 35.0);
            double dLon = TransformLon(wgLon - 105.0, wgLat - 35.0);
            double radLat = wgLat / 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 lat = wgLat + dLat;
            double lon = wgLon + dLon;
            point.SetLat(lat);
            point.SetLng(lon);
            return point;
        }


        public static void Transform(double wgLat, double wgLon, double[] latlng)
        {
            if (OutOfChina(wgLat, wgLon))
            {
                latlng[0] = wgLat;
                latlng[1] = wgLon;
                return;
            }
            double dLat = TransformLat(wgLon - 105.0, wgLat - 35.0);
            double dLon = TransformLon(wgLon - 105.0, wgLat - 35.0);
            double radLat = wgLat / 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);
            latlng[0] = wgLat + dLat;
            latlng[1] = wgLon + dLon;
        }

        private 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;
        }

        private 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;
        }

        private 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 class GPSPoint
    {
        private double lat;// 纬度
        private double lng;// 经度

        public GPSPoint()
        {
        }

        public GPSPoint(double lng, double lat)
        {
            this.lng = lng;
            this.lat = lat;
        }

        
        public double GetLat()
        {
            return lat;
        }
        public void SetLat(double lat)
        {
            this.lat = lat;
        }
        public double GetLng()
        {
            return lng;
        }
        public void SetLng(double lng)
        {
            this.lng = lng;
        }
        

    }

 

.

Java实现

package com.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);  
    }  
  
} 

 

.

js实现

var GPS = {
    PI : 3.14159265358979324,
    x_pi : 3.14159265358979324 * 3000.0 / 180.0,
    delta : function (lat, lon) {
        // Krasovsky 1940
        //
        // a = 6378245.0, 1/f = 298.3
        // b = a * (1 - f)
        // ee = (a^2 - b^2) / a^2;
        var a = 6378245.0; //  a: 卫星椭球坐标投影到平面地图坐标系的投影因子。
        var ee = 0.00669342162296594323; //  ee: 椭球的偏心率。
        var dLat = this.transformLat(lon - 105.0, lat - 35.0);
        var dLon = this.transformLon(lon - 105.0, lat - 35.0);
        var radLat = lat / 180.0 * this.PI;
        var magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        var sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * this.PI);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * this.PI);
        return {'lat': dLat, 'lon': dLon};
    },

    //WGS-84 to GCJ-02
    gcj_encrypt : function (wgsLat, wgsLon) {
        if (this.outOfChina(wgsLat, wgsLon))
            return {'lat': wgsLat, 'lon': wgsLon};

        var d = this.delta(wgsLat, wgsLon);
        return {'lat' : wgsLat + d.lat,'lon' : wgsLon + d.lon};
    },
    //GCJ-02 to WGS-84
    gcj_decrypt : function (gcjLat, gcjLon) {
        if (this.outOfChina(gcjLat, gcjLon))
            return {'lat': gcjLat, 'lon': gcjLon};

        var d = this.delta(gcjLat, gcjLon);
        return {'lat': gcjLat - d.lat, 'lon': gcjLon - d.lon};
    },
    //GCJ-02 to WGS-84 exactly
    gcj_decrypt_exact : function (gcjLat, gcjLon) {
        var initDelta = 0.01;
        var threshold = 0.000000001;
        var dLat = initDelta, dLon = initDelta;
        var mLat = gcjLat - dLat, mLon = gcjLon - dLon;
        var pLat = gcjLat + dLat, pLon = gcjLon + dLon;
        var wgsLat, wgsLon, i = 0;
        while (1) {
            wgsLat = (mLat + pLat) / 2;
            wgsLon = (mLon + pLon) / 2;
            var tmp = this.gcj_encrypt(wgsLat, wgsLon)
            dLat = tmp.lat - gcjLat;
            dLon = tmp.lon - gcjLon;
            if ((Math.abs(dLat) < threshold) && (Math.abs(dLon) < threshold))
                break;

            if (dLat > 0) pLat = wgsLat; else mLat = wgsLat;
            if (dLon > 0) pLon = wgsLon; else mLon = wgsLon;

            if (++i > 10000) break;
        }
        //console.log(i);
        return {'lat': wgsLat, 'lon': wgsLon};
    },
    //GCJ-02 to BD-09
    bd_encrypt : function (gcjLat, gcjLon) {
        var x = gcjLon, y = gcjLat;
        var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * this.x_pi);
        var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * this.x_pi);
        bdLon = z * Math.cos(theta) + 0.0065;
        bdLat = z * Math.sin(theta) + 0.006;
        return {'lat' : bdLat,'lon' : bdLon};
    },
    //BD-09 to GCJ-02
    bd_decrypt : function (bdLat, bdLon) {
        var x = bdLon - 0.0065, y = bdLat - 0.006;
        var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * this.x_pi);
        var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * this.x_pi);
        var gcjLon = z * Math.cos(theta);
        var gcjLat = z * Math.sin(theta);
        return {'lat' : gcjLat, 'lon' : gcjLon};
    },
    //WGS-84 to Web mercator
    //mercatorLat -> y mercatorLon -> x
    mercator_encrypt : function(wgsLat, wgsLon) {
        var x = wgsLon * 20037508.34 / 180.;
        var y = Math.log(Math.tan((90. + wgsLat) * this.PI / 360.)) / (this.PI / 180.);
        y = y * 20037508.34 / 180.;
        return {'lat' : y, 'lon' : x};
        /*
         if ((Math.abs(wgsLon) > 180 || Math.abs(wgsLat) > 90))
         return null;
         var x = 6378137.0 * wgsLon * 0.017453292519943295;
         var a = wgsLat * 0.017453292519943295;
         var y = 3189068.5 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));
         return {'lat' : y, 'lon' : x};
         //*/
    },
    // Web mercator to WGS-84
    // mercatorLat -> y mercatorLon -> x
    mercator_decrypt : function(mercatorLat, mercatorLon) {
        var x = mercatorLon / 20037508.34 * 180.;
        var y = mercatorLat / 20037508.34 * 180.;
        y = 180 / this.PI * (2 * Math.atan(Math.exp(y * this.PI / 180.)) - this.PI / 2);
        return {'lat' : y, 'lon' : x};
        /*
         if (Math.abs(mercatorLon) < 180 && Math.abs(mercatorLat) < 90)
         return null;
         if ((Math.abs(mercatorLon) > 20037508.3427892) || (Math.abs(mercatorLat) > 20037508.3427892))
         return null;
         var a = mercatorLon / 6378137.0 * 57.295779513082323;
         var x = a - (Math.floor(((a + 180.0) / 360.0)) * 360.0);
         var y = (1.5707963267948966 - (2.0 * Math.atan(Math.exp((-1.0 * mercatorLat) / 6378137.0)))) * 57.295779513082323;
         return {'lat' : y, 'lon' : x};
         //*/
    },
    // two point's distance
    distance : function (latA, lonA, latB, lonB) {
        var earthR = 6371000.;
        var x = Math.cos(latA * this.PI / 180.) * Math.cos(latB * this.PI / 180.) * Math.cos((lonA - lonB) * this.PI / 180);
        var y = Math.sin(latA * this.PI / 180.) * Math.sin(latB * this.PI / 180.);
        var s = x + y;
        if (s > 1) s = 1;
        if (s < -1) s = -1;
        var alpha = Math.acos(s);
        var distance = alpha * earthR;
        return distance;
    },
    outOfChina : function (lat, lon) {
        if (lon < 72.004 || lon > 137.8347)
            return true;
        if (lat < 0.8293 || lat > 55.8271)
            return true;
        return false;
    },
    transformLat : function (x, y) {
        var 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 * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(y * this.PI) + 40.0 * Math.sin(y / 3.0 * this.PI)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(y / 12.0 * this.PI) + 320 * Math.sin(y * this.PI / 30.0)) * 2.0 / 3.0;
        return ret;
    },
    transformLon : function (x, y) {
        var 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 * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(x * this.PI) + 40.0 * Math.sin(x / 3.0 * this.PI)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(x / 12.0 * this.PI) + 300.0 * Math.sin(x / 30.0 * this.PI)) * 2.0 / 3.0;
        return ret;
    }
};

 

.

 

发表在 gps | 地图坐标系的转换(WGS-84、GCJ-02、BD-09)已关闭评论