匹配已得地理位置的经纬度

所有代码与解析

数据经纬度匹配

我的数据是从链家网爬下来的数据,可以参考我的爬虫文章爬虫天津链家二手房数据(requests + BeautifulSoup)
其实链家有自己的经纬度,但是可能是网站加密的缘故,由于我技术有限,无法得到,就借助与高德API进行经纬度匹配

  1. 首先先去高德开发平台注册个账号(每天免费6000条,如果实名认证的话每天免费30w条数据,足够用了)
  2. 注册之后再应用界面创建新应用
    名字随便写,没有什么问题在这里插入图片描述
  3. 建好的应用选择添加选择web服务在这里插入图片描述
    在这里插入图片描述
    之后我们就利用这个key来调高德API进行经纬度匹配
import time
import pandas as pd
import numpy as np
import json
import requests
import re
from bs4 import BeautifulSoup


def get_loc(data):
    mc = data['小区名称']
    location1 = '天津' + mc
    loc = []
    bases = r"https://restapi.amap.com/v3/geocode/geo?address="+location1+"&output=XML&key=你刚刚注册来的key"
    for base in bases:
        try:
            response = requests.get(base)
            soupi = BeautifulSoup(response.text,'lxml')
            loc.append(soupi.find('location').text)
            print('成功采集一条位置数据,共采集%i'%(len(loc)))
        except:
            try:
                response = requests.get(base)
                soupi = BeautifulSoup(response.text,'lxml')
                loc.append(soupi.find('location').text)
                print('成功采集一条位置数据,共采集%i'%(len(loc)))
            except:
                print('未成功采集两次,未成功采集的网址为',base)
                loc.append(np.nan)
    return loc

#locationplus = get_loc(data)
#data = pd.DataFrame()
#data['小区名称'] = ['市政府']
#data_use = data
if __name__ == "__main__":
	#注意改路径
    data = pd.read_excel(r'F:\I_love_learning\junior\数据挖掘与数据仓库\课程设计\dataxiaoqu.xlsx')
    data = data[['单价','小区名称']]
    data_use = data
    locationplus = get_loc(data_use)
    data_use['经纬度'] = locationplus
    data_use['lng'] = data_use['经纬度'].str.split(',').str[0]
    data_use['lat'] = data_use['经纬度'].str.split(',').str[1]
    data_use.to_excel(r'F:\I_love_learning\junior\数据挖掘与数据仓库\课程设计\dataxiaoqu2.xlsx')
    

这样经纬度匹配就完事了

转换为WGS84坐标

如果你想用到QGIS作图和数据处理,需要转换为WGS84坐标
当然,直接用excel作图就不用转换,excel作图就是用的火星坐标

import json
import math
import pandas as pd
x_pi = 3.14159265358979324 * 3000.0 / 180.0
pi = 3.1415926535897932384626  # π
a = 6378245.0  # 长半轴
ee = 0.00669342162296594323  # 扁率

def wgs84togcj02(lng, lat):
    """
    WGS84转GCJ02(火星坐标系)
    :param lng:WGS84坐标系的经度
    :param lat:WGS84坐标系的纬度
    :return:
    """
    if out_of_china(lng, lat):  # 判断是否在国内
        return lng, lat
    dlat = transformlat(lng - 105.0, lat - 35.0)
    dlng = transformlng(lng - 105.0, lat - 35.0)
    radlat = lat / 180.0 * pi
    magic = math.sin(radlat)
    magic = 1 - ee * magic * magic
    sqrtmagic = math.sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
    dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)
    mglat = lat + dlat
    mglng = lng + dlng
    return [mglng, mglat]


def gcj02towgs84(lng, lat):
    """
    GCJ02(火星坐标系)转GPS84
    :param lng:火星坐标系的经度
    :param lat:火星坐标系纬度
    :return:
    """
    #if out_of_china(lng, lat):
     #   return lng, lat
    dlat = transformlat(lng - 105.0, lat - 35.0)
    dlng = transformlng(lng - 105.0, lat - 35.0)
    radlat = lat / 180.0 * pi
    magic = math.sin(radlat)
    magic = 1 - ee * magic * magic
    sqrtmagic = math.sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
    dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)
    mglat = lat + dlat
    mglng = lng + dlng
    return [lng * 2 - mglng, lat * 2 - mglat]


def transformlat(lng, lat):
    ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + \
        0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng))
    ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
            math.sin(2.0 * lng * pi)) * 2.0 / 3.0
    ret += (20.0 * math.sin(lat * pi) + 40.0 *
            math.sin(lat / 3.0 * pi)) * 2.0 / 3.0
    ret += (160.0 * math.sin(lat / 12.0 * pi) + 320 *
            math.sin(lat * pi / 30.0)) * 2.0 / 3.0
    return ret


def transformlng(lng, lat):
    ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + \
        0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng))
    ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
            math.sin(2.0 * lng * pi)) * 2.0 / 3.0
    ret += (20.0 * math.sin(lng * pi) + 40.0 *
            math.sin(lng / 3.0 * pi)) * 2.0 / 3.0
    ret += (150.0 * math.sin(lng / 12.0 * pi) + 300.0 *
            math.sin(lng / 30.0 * pi)) * 2.0 / 3.0
    return ret


def out_of_china(lng, lat):
    """
    判断是否在国内,不在国内不做偏移
    :param lng:
    :param lat:
    :return:
    """
    if lng <= 72.004 or lng >= 137.8347:
        return True
    if lat < 0.8293 or lat > 55.8271:
        return True
    return False

#loc_data = data_use

if __name__ == '__main__':
    loc_data = pd.read_csv('F:\I_love_learning\junior\数据挖掘与数据仓库\课程设计\pro10data.csv')
    lat = loc_data['lat'].tolist()
    lng = loc_data['lng'].tolist()
    result = []
    for i in range(len(lng)):

        result.append(gcj02towgs84(lng[i], lat[i]))
    
    result_r = pd.DataFrame(result)
    result_r.columns = ['lng','lat']
    loc_data[['lat','lng']] = result_r
    loc_data.to_csv('pro10data2.csv')

也可以匹配之后进行下数据预处理

# -*- coding: utf-8 -*-
"""
Created on Thu Mar  4 09:28:06 2021

@author: 89344
"""
import time
import pandas as pd
import numpy as np
import json
import requests
import re
from bs4 import BeautifulSoup

import json
import math
x_pi = 3.14159265358979324 * 3000.0 / 180.0
pi = 3.1415926535897932384626  # π
a = 6378245.0  # 长半轴
ee = 0.00669342162296594323  # 扁率

def wgs84togcj02(lng, lat):
    """
    WGS84转GCJ02(火星坐标系)
    :param lng:WGS84坐标系的经度
    :param lat:WGS84坐标系的纬度
    :return:
    """
    if out_of_china(lng, lat):  # 判断是否在国内
        return lng, lat
    dlat = transformlat(lng - 105.0, lat - 35.0)
    dlng = transformlng(lng - 105.0, lat - 35.0)
    radlat = lat / 180.0 * pi
    magic = math.sin(radlat)
    magic = 1 - ee * magic * magic
    sqrtmagic = math.sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
    dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)
    mglat = lat + dlat
    mglng = lng + dlng
    return [mglng, mglat]


def gcj02towgs84(lng, lat):
    """
    GCJ02(火星坐标系)转GPS84
    :param lng:火星坐标系的经度
    :param lat:火星坐标系纬度
    :return:
    """
    #if out_of_china(lng, lat):
     #   return lng, lat
    dlat = transformlat(lng - 105.0, lat - 35.0)
    dlng = transformlng(lng - 105.0, lat - 35.0)
    radlat = lat / 180.0 * pi
    magic = math.sin(radlat)
    magic = 1 - ee * magic * magic
    sqrtmagic = math.sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
    dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)
    mglat = lat + dlat
    mglng = lng + dlng
    return [lng * 2 - mglng, lat * 2 - mglat]


def transformlat(lng, lat):
    ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + \
        0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng))
    ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
            math.sin(2.0 * lng * pi)) * 2.0 / 3.0
    ret += (20.0 * math.sin(lat * pi) + 40.0 *
            math.sin(lat / 3.0 * pi)) * 2.0 / 3.0
    ret += (160.0 * math.sin(lat / 12.0 * pi) + 320 *
            math.sin(lat * pi / 30.0)) * 2.0 / 3.0
    return ret


def transformlng(lng, lat):
    ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + \
        0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng))
    ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
            math.sin(2.0 * lng * pi)) * 2.0 / 3.0
    ret += (20.0 * math.sin(lng * pi) + 40.0 *
            math.sin(lng / 3.0 * pi)) * 2.0 / 3.0
    ret += (150.0 * math.sin(lng / 12.0 * pi) + 300.0 *
            math.sin(lng / 30.0 * pi)) * 2.0 / 3.0
    return ret


def out_of_china(lng, lat):
    """
    判断是否在国内,不在国内不做偏移
    :param lng:
    :param lat:
    :return:
    """
    if lng <= 72.004 or lng >= 137.8347:
        return True
    if lat < 0.8293 or lat > 55.8271:
        return True
    return False



def data_cleaning2():
    data = pd.read_excel(r'F:\I_love_learning\junior\数据挖掘与数据仓库\课程设计\dataxiaoqu2.xlsx')
    data = data[['小区名称','单价','lng','lat']]

    lat = data['lat'].tolist()
    lng = data['lng'].tolist()

    result = []
    for i in range(len(lng)):

        result.append(gcj02towgs84(lng[i], lat[i]))
    
    result_r = pd.DataFrame(result)
    result_r.columns = ['lng','lat']
    data[['lng','lat']] = result_r
    data['小区名称'] = data['小区名称'] + ' '
    data.to_csv(r'F:\I_love_learning\junior\数据挖掘与数据仓库\课程设计\dataxiaoqu3.csv',encoding='utf-8')

if __name__ == "__main__":

    data_cleaning2()
匹配好小区的经纬度之后,房屋的经纬度就唾手可得了

直接利用pandas中的连接方法即可获取
当然,重新匹配一遍也是可以的

# -*- coding: utf-8 -*-
"""
Created on Thu Mar  4 09:28:06 2021

@author: 89344
"""
import time
import pandas as pd
import numpy as np
import json
import requests
import re
from bs4 import BeautifulSoup
def data_cleaning1():
    data = pd.read_excel(r'F:\I_love_learning\junior\数据挖掘与数据仓库\课程设计\dataroom.xlsx')
    data['挂牌时间'] = data['挂牌时间'].str.split('间').str[1]
    data['挂牌时间'] = pd.to_datetime(data['挂牌时间']).dt.date

    location = pd.read_excel(r'F:\I_love_learning\junior\数据挖掘与数据仓库\课程设计\dataxiaoqu2.xlsx')
    #去除\xa0
    data_loc = pd.merge(data,location[['小区名称','lng','lat']],on = '小区名称')
    data['总价'] = data['总价'].str.split('万').str[0].astype('float')
    data['单价'] = data['单价'].str.split('元').str[0].astype('int')
    data['面积'] = data['面积'].str.split('平').str[0].astype('float')
    '''
    m = data['所在区域']
    mresu = []
    for mi in m:
        mi = ''.join(mi.split())
        mresu.append(mi)
    data['所在区域'] = mresu
    data['经纬度'] = get_loc(data)   
    data['lng'] = data['经纬度'].str.split(',').str[0]
    data['lat'] = data['经纬度'].str.split(',').str[1]
    '''
    data.to_excel(r'F:\I_love_learning\junior\数据挖掘与数据仓库\课程设计\dataroom2.xlsx')

'''
def get_loc(data):
    mc = data['所在区域']+ data['小区名称']
    location1 = '天津' + mc
    loc = []
    bases = r"https://restapi.amap.com/v3/geocode/geo?address="+location1+"&output=XML&key=a2d86849d5be62148caf5fd6cce5bf7d"
    for base in bases:
        try:
            response = requests.get(base)
            soupi = BeautifulSoup(response.text,'lxml')
            loc.append(soupi.find('location').text)
            print('成功采集一条位置数据')
        except:
            try:
                response = requests.get(base)
                soupi = BeautifulSoup(response.text,'lxml')
                loc.append(soupi.find('location').text)
                print('成功采集一条位置数据')
            except:
                print('未成功采集两次,未成功采集的网址为',base)
                loc.append(np.nan)
    return loc
'''
if __name__ == "__main__":

    data_cleaning1()
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_yuan20

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值