流程:
【1】c语言编写逆地理编码的函数,利用curl库和高德服务器进行地理坐标解析
【2】gcc生成动态链接库
【3】postgreSQL中加载动态链接库中的函数
【4】postgreSQL中将逆地理编码函数的返回类型进行转化
===========================================
【1】c语言编写逆地理编码的函数,利用curl库和高德服务器进行地理坐标解析
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include "postgres.h"
#include "fmgr.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
int StringFind(char *pSrc, char *pDst)//字符串位置查找,返回源字符串的位置
{
int i, j;
for (i=0; pSrc[i]!='\0'; i++)
{
if(pSrc[i]!=pDst[0])
continue;
j = 0;
while(pDst[j]!='\0' && pSrc[i+j]!='\0')
{
j++;
if(pDst[j]!=pSrc[i+j])
break;
}
if(pDst[j]=='\0')
return i;
}
return -1;
}
size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)//回调函数
{
strcat((char*)userdata, (char*)ptr);
return size*nmemb;
}
char* poi_list(char* longitude, char* latitude) { //主函数
int mPos = 0;
int mNewPos = 0;
char* pResult = NULL;
char* pDst = "poi_list";
char finalResult[5120] = {'\0'};
int i = 0;
char strResult[5120] = {'\0'};//结果存储
char szpage[256] = "http://ditu.amap.com/service/regeo?";
char tempLongitude[25] = "longitude=";
char tempLatitude[25] = "&latitude=";
char* pstrLongitude = strcat(tempLongitude,longitude);
char* pstrLatitude = strcat(tempLatitude,latitude);
char* locationInfor = strcat(pstrLongitude,pstrLatitude);
char* myurl = strcat(szpage,locationInfor);
CURLcode res;
res = curl_global_init(CURL_GLOBAL_ALL);//初始化
if (res != CURLE_OK)
{
pResult = psprintf( "Failed to global init default [%d]\n", res );
return pResult;
}
CURL* pEasyHandle = curl_easy_init(); // 初始化
curl_easy_setopt(pEasyHandle, CURLOPT_URL, myurl);//传入url
curl_easy_setopt(pEasyHandle, CURLOPT_WRITEFUNCTION, &write_callback);//调用回调函数
curl_easy_setopt(pEasyHandle, CURLOPT_TIMEOUT, 10);
curl_easy_setopt(pEasyHandle, CURLOPT_FORBID_REUSE, 1);
curl_easy_setopt(pEasyHandle, CURLOPT_WRITEDATA, strResult);//参数三对应回调函数的参数四
res = curl_easy_perform(pEasyHandle);
curl_easy_cleanup(pEasyHandle);
mPos=StringFind(strResult,pDst);
mNewPos=mPos+10;//过滤掉location字段
while(strResult[mNewPos]!='\0')
{
finalResult[i]=strResult[mNewPos];
mNewPos++;
i++;
}
i=i-2;
finalResult[i]='\0';
size_t strLength = strlen(finalResult) + 1;
pResult = malloc(strLength);
strcpy(pResult, finalResult);
return pResult;
}
【2】gcc生成动态链接库
hyc@hyc-csu:~/文档/Curl_program$ gcc -fpic -I `pg_config --includedir-server` -c poiOutput.c -lcurl
hyc@hyc-csu:~/文档/Curl_program$ gcc -fpic -shared -o poiOutput.so poiOutput.o -lcurl
hyc@hyc-csu:~/文档/Curl_program$ sudo cp poiOutput.so `pg_config --libdir`
【3】postgreSQL中加载动态链接库中的函数【与MFC(Microsoft Foundation Classes)中的CString类不同,cstring是一种pseudo type,详见文档】
gpsDB=# load 'poiOutput.so';
LOAD
gpsDB=# create function poi_list(cstring,cstring)
returns cstring
as 'poiOutput.so','poi_list'
language C immutable strict;
CREATE FUNCTION
gpsDB=# select poi_list('118.744607','32.030886');
【4】postgreSQL中将逆地理编码函数的返回类型进行转化【参数null::poiarray,其中poiarray表结构与json结构相对应,详情点击此处】
gpsDB=# select (select poi_list('112.931850','28.169100'))::json;
ERROR: cannot cast type cstring to json //cstring类型转化为text类型,再转化为json类型
gpsDB=# select * from json_populate_recordset(null::poiarray,(cast((select poi_list('118.744607','32.030886')) as text))::json);
gpsDB=# select * from json_populate_recordset(null::poiarray,(poi_list('118.744607','32.030886')::text)::json);