geoc-pg-coordtransform.sql 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574
  1. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02_polygon"("source_geom" "public"."geometry")
  2. RETURNS "public"."geometry" AS $BODY$
  3. DECLARE
  4. target_parts geometry[];
  5. source_npoints integer;
  6. single_line geometry;
  7. single_line_trans geometry;
  8. single_polygon geometry;
  9. final_geom geometry;
  10. BEGIN
  11. IF ST_GeometryType(source_geom) != 'ST_Polygon' THEN
  12. RETURN null;
  13. END IF;
  14. FOR single_polygon IN SELECT ST_ExteriorRing ((st_dumprings($1)).geom) as geom LOOP
  15. source_npoints := ST_NPoints(single_polygon);
  16. single_line := ST_RemovePoint(single_polygon, source_npoints - 1);
  17. single_line_trans := geoc_wgs84togcj02_line(single_line);
  18. target_parts := array_append(target_parts, ST_AddPoint(single_line_trans, ST_PointN(single_line_trans, 1)));
  19. END LOOP;
  20. SELECT ST_MakePolygon(target_parts[1], target_parts[2:array_upper(target_parts, 1)]) INTO final_geom;
  21. -- raise NOTICE 'final_geom: %',final_geom;
  22. RETURN final_geom;
  23. END;
  24. $BODY$
  25. LANGUAGE plpgsql VOLATILE
  26. COST 100;
  27. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02_point"("geom" "public"."geometry")
  28. RETURNS "public"."geometry" AS $BODY$
  29. DECLARE
  30. lon numeric;
  31. lat numeric;
  32. d jsonb;
  33. dlon numeric;
  34. dlat numeric;
  35. BEGIN
  36. if st_geometrytype(geom) != 'ST_Point' then
  37. return null;
  38. end if;
  39. lon := st_x(geom);
  40. lat := st_y(geom);
  41. if (geoc_is_in_china_bbox(lon, lat) = false) then
  42. return geom;
  43. end if;
  44. d := geoc_delta(lon, lat);
  45. dlon := d->0;
  46. dlat := d->1;
  47. return st_makepoint(lon + dlon,lat + dlat);
  48. END;
  49. $BODY$
  50. LANGUAGE plpgsql VOLATILE
  51. COST 100;
  52. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02"("coord" _numeric)
  53. RETURNS "pg_catalog"."_numeric" AS $BODY$
  54. DECLARE
  55. ret numeric[];
  56. dLon numeric;
  57. dlat numeric;
  58. lon numeric;
  59. lat numeric;
  60. d jsonb;
  61. -- coord ARRAY;
  62. BEGIN
  63. lon := coord[1];
  64. lat := coord[2];
  65. if (geoc_is_in_china_bbox(lon, lat) = false) then
  66. return coord;
  67. end if;
  68. d := geoc_delta(lon, lat);
  69. dlon := d->0;
  70. dlat := d->1;
  71. ret := ARRAY[lon + dlon , lat + dlat];
  72. return ret;
  73. END;
  74. $BODY$
  75. LANGUAGE plpgsql VOLATILE
  76. COST 100;
  77. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02_multipolygon"("source_geom" "public"."geometry")
  78. RETURNS "public"."geometry" AS $BODY$
  79. DECLARE
  80. target_parts geometry[];
  81. single_polygon geometry;
  82. single_polygon_trans geometry;
  83. final_geom geometry;
  84. BEGIN
  85. IF ST_GeometryType(source_geom) != 'ST_MultiPolygon' THEN
  86. RETURN null;
  87. END IF;
  88. FOR single_polygon IN SELECT (ST_Dump($1)).geom LOOP
  89. single_polygon_trans := geoc_wgs84togcj02_polygon(single_polygon);
  90. target_parts := array_append(target_parts,single_polygon_trans);
  91. END LOOP;
  92. SELECT st_multi(ST_Union(target_parts)) INTO final_geom;
  93. raise NOTICE 'final_geom: %',final_geom;
  94. RETURN final_geom;
  95. END;
  96. $BODY$
  97. LANGUAGE plpgsql VOLATILE
  98. COST 100;
  99. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02_multipoint"("geom" "public"."geometry")
  100. RETURNS "public"."geometry" AS $BODY$
  101. DECLARE
  102. i geometry;
  103. transform_i geometry;
  104. multiArr geometry[];
  105. BEGIN
  106. multiArr:='{}'::geometry[];
  107. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  108. transform_i :=geoc_wgs84togcj02_point(i);
  109. multiArr := array_append(multiArr, transform_i);
  110. end LOOP;
  111. return st_multi(ST_Union(multiArr));
  112. END;
  113. $BODY$
  114. LANGUAGE plpgsql VOLATILE
  115. COST 100;
  116. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02_multiline"("geom" "public"."geometry")
  117. RETURNS "public"."geometry" AS $BODY$
  118. DECLARE
  119. i geometry;
  120. transform_i geometry;
  121. multiArr geometry[];
  122. BEGIN
  123. multiArr:='{}'::geometry[];
  124. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  125. transform_i :=geoc_wgs84togcj02_line(i);
  126. multiArr := array_append(multiArr, transform_i);
  127. end LOOP;
  128. return st_multi(ST_Union(multiArr));
  129. END;
  130. $BODY$
  131. LANGUAGE plpgsql VOLATILE
  132. COST 100;
  133. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02_line"("geom" "public"."geometry")
  134. RETURNS "public"."geometry" AS $BODY$
  135. DECLARE
  136. p_p geometry;
  137. p_t geometry;
  138. z_t geometry;
  139. i int;
  140. BEGIN
  141. i:=1;
  142. while i <= st_npoints(geom) LOOP
  143. p_p := st_pointn(geom,i);
  144. p_t := geoc_wgs84togcj02_point(p_p);
  145. geom:=st_setpoint(geom,i-1,p_t);
  146. i:=i+1;
  147. end LOOP;
  148. return geom;
  149. END;
  150. $BODY$
  151. LANGUAGE plpgsql VOLATILE
  152. COST 100;
  153. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02"("geom" "public"."geometry")
  154. RETURNS "public"."geometry" AS $BODY$
  155. DECLARE
  156. i geometry;
  157. transform_i geometry;
  158. multiArr geometry[];
  159. BEGIN
  160. IF st_srid(geom) != 4490 and st_srid(geom) != 4326 THEN
  161. RETURN null;
  162. end if;
  163. CASE ST_GeometryType(geom)
  164. when 'ST_LineString' then
  165. return geoc_wgs84togcj02_line(geom);
  166. when 'ST_MultiLineString' then
  167. return geoc_wgs84togcj02_multiline(geom);
  168. when 'ST_Point' then
  169. return geoc_wgs84togcj02_point(geom);
  170. when 'ST_MultiPoint' then
  171. return geoc_wgs84togcj02_multipoint(geom);
  172. when 'ST_Polygon' then
  173. return geoc_wgs84togcj02_polygon(geom);
  174. when 'ST_MultiPolygon' then
  175. return geoc_wgs84togcj02_multipolygon(geom);
  176. ELSE
  177. RETURN null;
  178. END CASE;
  179. END;
  180. $BODY$
  181. LANGUAGE plpgsql VOLATILE
  182. COST 100;
  183. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84tobd09_polygon"("source_geom" "public"."geometry")
  184. RETURNS "public"."geometry" AS $BODY$
  185. DECLARE
  186. target_parts geometry[];
  187. source_npoints integer;
  188. single_line geometry;
  189. single_line_trans geometry;
  190. single_polygon geometry;
  191. final_geom geometry;
  192. BEGIN
  193. IF ST_GeometryType(source_geom) != 'ST_Polygon' THEN
  194. RETURN null;
  195. END IF;
  196. FOR single_polygon IN SELECT ST_ExteriorRing ((st_dumprings($1)).geom) as geom LOOP
  197. source_npoints := ST_NPoints(single_polygon);
  198. single_line := ST_RemovePoint(single_polygon, source_npoints - 1);
  199. single_line_trans := geoc_wgs84tobd09_line(single_line);
  200. target_parts := array_append(target_parts, ST_AddPoint(single_line_trans, ST_PointN(single_line_trans, 1)));
  201. END LOOP;
  202. SELECT ST_MakePolygon(target_parts[1], target_parts[2:array_upper(target_parts, 1)]) INTO final_geom;
  203. -- raise NOTICE 'final_geom: %',final_geom;
  204. RETURN final_geom;
  205. END;
  206. $BODY$
  207. LANGUAGE plpgsql VOLATILE
  208. COST 100;
  209. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84tobd09_point"("geom" "public"."geometry")
  210. RETURNS "public"."geometry" AS $BODY$
  211. DECLARE
  212. lon numeric;
  213. lat numeric;
  214. bd_point geometry;
  215. gcj_point geometry;
  216. BEGIN
  217. if st_geometrytype(geom) != 'ST_Point' then
  218. return null;
  219. end if;
  220. lon := st_x(geom);
  221. lat := st_y(geom);
  222. if geoc_is_in_china_bbox(lon, lat) = false THEN
  223. return geom;
  224. end if;
  225. gcj_point = geoc_wgs84togcj02_point(geom);
  226. bd_point = geoc_gcj02tobd09_point(gcj_point);
  227. return bd_point;
  228. END;
  229. $BODY$
  230. LANGUAGE plpgsql VOLATILE
  231. COST 100;
  232. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84tobd09_multipolygon"("source_geom" "public"."geometry")
  233. RETURNS "public"."geometry" AS $BODY$
  234. DECLARE
  235. target_parts geometry[];
  236. single_polygon geometry;
  237. single_polygon_trans geometry;
  238. final_geom geometry;
  239. BEGIN
  240. IF ST_GeometryType(source_geom) != 'ST_MultiPolygon' THEN
  241. RETURN null;
  242. END IF;
  243. FOR single_polygon IN SELECT (ST_Dump($1)).geom LOOP
  244. single_polygon_trans := geoc_wgs84tobd09_polygon(single_polygon);
  245. target_parts := array_append(target_parts,single_polygon_trans);
  246. END LOOP;
  247. SELECT st_multi(ST_Union(target_parts)) INTO final_geom;
  248. raise NOTICE 'final_geom: %',final_geom;
  249. RETURN final_geom;
  250. END;
  251. $BODY$
  252. LANGUAGE plpgsql VOLATILE
  253. COST 100;
  254. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84tobd09_multipoint"("geom" "public"."geometry")
  255. RETURNS "public"."geometry" AS $BODY$
  256. DECLARE
  257. i geometry;
  258. transform_i geometry;
  259. multiArr geometry[];
  260. BEGIN
  261. multiArr:='{}'::geometry[];
  262. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  263. transform_i :=geoc_wgs84tobd09_point(i);
  264. multiArr := array_append(multiArr, transform_i);
  265. end LOOP;
  266. return st_multi(ST_Union(multiArr));
  267. END;
  268. $BODY$
  269. LANGUAGE plpgsql VOLATILE
  270. COST 100;
  271. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84tobd09_multiline"("geom" "public"."geometry")
  272. RETURNS "public"."geometry" AS $BODY$
  273. DECLARE
  274. i geometry;
  275. transform_i geometry;
  276. multiArr geometry[];
  277. BEGIN
  278. multiArr:='{}'::geometry[];
  279. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  280. transform_i :=geoc_wgs84tobd09_line(i);
  281. multiArr := array_append(multiArr, transform_i);
  282. end LOOP;
  283. return st_multi(ST_Union(multiArr));
  284. END;
  285. $BODY$
  286. LANGUAGE plpgsql VOLATILE
  287. COST 100;
  288. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84tobd09_line"("geom" "public"."geometry")
  289. RETURNS "public"."geometry" AS $BODY$
  290. DECLARE
  291. p_p geometry;
  292. p_t geometry;
  293. z_t geometry;
  294. i int;
  295. BEGIN
  296. i:=1;
  297. while i <= st_npoints(geom) LOOP
  298. p_p := st_pointn(geom,i);
  299. p_t := geoc_wgs84tobd09_point(p_p);
  300. geom:=st_setpoint(geom,i-1,p_t);
  301. i:=i+1;
  302. end LOOP;
  303. return geom;
  304. END;
  305. $BODY$
  306. LANGUAGE plpgsql VOLATILE
  307. COST 100;
  308. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84tobd09"("geom" "public"."geometry")
  309. RETURNS "public"."geometry" AS $BODY$
  310. DECLARE
  311. BEGIN
  312. -- IF st_srid(geom) != '4490' THEN
  313. -- RETURN null;
  314. -- end if;
  315. -- IF st_srid(geom) != '4326' THEN
  316. -- RETURN null;
  317. -- end if;
  318. case ST_GeometryType(geom)
  319. when 'ST_LineString' then
  320. return geoc_wgs84tobd09_line(geom);
  321. when 'ST_MultiLineString' then
  322. return geoc_wgs84tobd09_multiline(geom);
  323. when 'ST_Point' then
  324. return geoc_wgs84tobd09_point(geom);
  325. when 'ST_MultiPoint' then
  326. return geoc_wgs84tobd09_multipoint(geom);
  327. when 'ST_Polygon' then
  328. return geoc_wgs84tobd09_polygon(geom);
  329. when 'ST_MultiPolygon' then
  330. return geoc_wgs84tobd09_multipolygon(geom);
  331. ELSE
  332. RETURN null;
  333. END CASE;
  334. END;
  335. $BODY$
  336. LANGUAGE plpgsql VOLATILE
  337. COST 100;
  338. CREATE OR REPLACE FUNCTION "public"."geoc_transform_lon"("x" numeric, "y" numeric)
  339. RETURNS "pg_catalog"."numeric" AS $BODY$
  340. DECLARE
  341. ret numeric;
  342. BEGIN
  343. ret := 300 + x + 2 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(abs(x));
  344. ret :=ret + (20 * sin(6 * x * pi()) + 20 * sin(2 * x * pi())) * 2 / 3;
  345. ret :=ret + (20 * sin(x * pi()) + 40 * sin(x / 3 * pi())) * 2 / 3;
  346. ret :=ret + (150 * sin(x / 12 * pi()) + 300 * sin(x / 30 * pi())) * 2 / 3;
  347. return ret;
  348. END;
  349. $BODY$
  350. LANGUAGE plpgsql VOLATILE
  351. COST 100;
  352. CREATE OR REPLACE FUNCTION "public"."geoc_transform_lat"("x" numeric, "y" numeric)
  353. RETURNS "pg_catalog"."numeric" AS $BODY$
  354. DECLARE
  355. ret numeric;
  356. BEGIN
  357. ret := -100 + 2 * x + 3 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(abs(x));
  358. ret := ret + (20 * sin(6 * x * PI()) + 20 * sin(2 * x * PI())) * 2 / 3;
  359. ret := ret +(20 * sin(y * PI()) + 40 * sin(y / 3 * PI())) * 2 / 3;
  360. ret := ret +(160 * sin(y / 12 * PI()) + 320 * sin(y * PI() / 30)) * 2 / 3;
  361. return ret;
  362. END;
  363. $BODY$
  364. LANGUAGE plpgsql VOLATILE
  365. COST 100;
  366. CREATE OR REPLACE FUNCTION "public"."geoc_is_in_china_bbox"("lon" numeric, "lat" numeric)
  367. RETURNS "pg_catalog"."bool" AS $BODY$
  368. DECLARE
  369. BEGIN
  370. return lon >= 72.004 and lon <= 137.8347 and lat >= 0.8293 and lat <= 55.8271;
  371. END;
  372. $BODY$
  373. LANGUAGE plpgsql VOLATILE
  374. COST 100;
  375. CREATE OR REPLACE FUNCTION "public"."geoc_delta"("lon" numeric, "lat" numeric)
  376. RETURNS "pg_catalog"."jsonb" AS $BODY$
  377. DECLARE
  378. ret varchar;
  379. dLon numeric;
  380. dlat numeric;
  381. radLat numeric;
  382. magic numeric;
  383. sqrtMagic numeric;
  384. ee numeric;
  385. a numeric;
  386. BEGIN
  387. ee := 0.006693421622965823;
  388. a := 6378245;
  389. dLon := geoc_transform_lon(lon - 105, lat - 35);
  390. dLat := geoc_transform_lat(lon - 105, lat - 35);
  391. --raise NOTICE 'dLon的值为: %',dLon;
  392. --raise NOTICE 'dLat的值为: %',dLat;
  393. radLat := lat / 180 * pi();
  394. magic = sin(radLat);
  395. magic = 1 - ee * magic * magic;
  396. sqrtMagic := sqrt(magic);
  397. dLon = (dLon * 180) / (a / sqrtMagic * cos(radLat) * pi());
  398. dLat = (dLat * 180) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi());
  399. ret :='['||dLon||','||dLat||']';
  400. return ret::jsonb;
  401. END;
  402. $BODY$
  403. LANGUAGE plpgsql VOLATILE
  404. COST 100;
  405. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02towgs84_line"("geom" "public"."geometry")
  406. RETURNS "public"."geometry" AS $BODY$
  407. DECLARE
  408. p_p geometry;
  409. p_t geometry;
  410. z_t geometry;
  411. i int;
  412. BEGIN
  413. i:=1;
  414. while i <= st_npoints(geom) LOOP
  415. p_p := st_pointn(geom,i);
  416. p_t := geoc_gcj02towgs84_point(p_p);
  417. geom:=st_setpoint(geom,i-1,p_t);
  418. i:=i+1;
  419. end LOOP;
  420. return geom;
  421. END;
  422. $BODY$
  423. LANGUAGE plpgsql VOLATILE
  424. COST 100;
  425. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02towgs84_multiline"("geom" "public"."geometry")
  426. RETURNS "public"."geometry" AS $BODY$
  427. DECLARE
  428. i geometry;
  429. transform_i geometry;
  430. multiArr geometry[];
  431. BEGIN
  432. multiArr:='{}'::geometry[];
  433. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  434. transform_i :=geoc_gcj02towgs84_line(i);
  435. multiArr := array_append(multiArr, transform_i);
  436. end LOOP;
  437. return st_multi(ST_Union(multiArr));
  438. END;
  439. $BODY$
  440. LANGUAGE plpgsql VOLATILE
  441. COST 100;
  442. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02towgs84_multipoint"("geom" "public"."geometry")
  443. RETURNS "public"."geometry" AS $BODY$
  444. DECLARE
  445. i geometry;
  446. transform_i geometry;
  447. multiArr geometry[];
  448. BEGIN
  449. multiArr:='{}'::geometry[];
  450. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  451. transform_i :=geoc_gcj02towgs84_point(i);
  452. multiArr := array_append(multiArr, transform_i);
  453. end LOOP;
  454. return st_multi(ST_Union(multiArr));
  455. END;
  456. $BODY$
  457. LANGUAGE plpgsql VOLATILE
  458. COST 100;
  459. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02towgs84_multipolygon"("source_geom" "public"."geometry")
  460. RETURNS "public"."geometry" AS $BODY$
  461. DECLARE
  462. target_parts geometry[];
  463. single_polygon geometry;
  464. single_polygon_trans geometry;
  465. final_geom geometry;
  466. BEGIN
  467. IF ST_GeometryType(source_geom) != 'ST_MultiPolygon' THEN
  468. RETURN source_geom;
  469. END IF;
  470. FOR single_polygon IN SELECT (ST_Dump($1)).geom LOOP
  471. single_polygon_trans := geoc_gcj02towgs84_polygon(single_polygon);
  472. target_parts := array_append(target_parts,single_polygon_trans);
  473. END LOOP;
  474. SELECT st_multi(ST_Union(target_parts)) INTO final_geom;
  475. raise NOTICE 'final_geom: %',final_geom;
  476. RETURN final_geom;
  477. END;
  478. $BODY$
  479. LANGUAGE plpgsql VOLATILE
  480. COST 100;
  481. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02towgs84_point"("geom" "public"."geometry")
  482. RETURNS "public"."geometry" AS $BODY$
  483. DECLARE
  484. tempPoint numeric[];
  485. wgsLon numeric;
  486. wgsLat numeric;
  487. lon numeric;
  488. lat numeric;
  489. BEGIN
  490. if st_geometrytype(geom) != 'ST_Point' then
  491. return geom;
  492. end if;
  493. lon := st_x(geom);
  494. lat := st_y(geom);
  495. if geoc_is_in_china_bbox(lon, lat) = false THEN
  496. return geom;
  497. end if;
  498. tempPoint := geoc_wgs84togcj02(ARRAY[lon, lat]);
  499. wgsLon := lon*2 - tempPoint[1];
  500. wgsLat := lat*2 - tempPoint[2];
  501. return st_makepoint(wgsLon,wgsLat);
  502. END;
  503. $BODY$
  504. LANGUAGE plpgsql VOLATILE
  505. COST 100;
  506. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02towgs84_polygon"("source_geom" "public"."geometry")
  507. RETURNS "public"."geometry" AS $BODY$
  508. DECLARE
  509. target_parts geometry[];
  510. source_npoints integer;
  511. single_line geometry;
  512. single_line_trans geometry;
  513. single_polygon geometry;
  514. final_geom geometry;
  515. BEGIN
  516. IF ST_GeometryType(source_geom) != 'ST_Polygon' THEN
  517. RETURN source_geom;
  518. END IF;
  519. FOR single_polygon IN SELECT ST_ExteriorRing ((st_dumprings($1)).geom) as geom LOOP
  520. source_npoints := ST_NPoints(single_polygon);
  521. single_line := ST_RemovePoint(single_polygon, source_npoints - 1);
  522. single_line_trans := geoc_gcj02towgs84_line(single_line);
  523. target_parts := array_append(target_parts, ST_AddPoint(single_line_trans, ST_PointN(single_line_trans, 1)));
  524. END LOOP;
  525. SELECT ST_MakePolygon(target_parts[1], target_parts[2:array_upper(target_parts, 1)]) INTO final_geom;
  526. -- raise NOTICE 'final_geom: %',final_geom;
  527. RETURN final_geom;
  528. END;
  529. $BODY$
  530. LANGUAGE plpgsql VOLATILE
  531. COST 100;
  532. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02towgs84"("geom" "public"."geometry")
  533. RETURNS "public"."geometry" AS $BODY$
  534. DECLARE
  535. BEGIN
  536. IF st_srid(geom) != 4490 and st_srid(geom) != 4326 THEN
  537. RETURN null;
  538. end if;
  539. case ST_GeometryType(geom)
  540. when 'ST_LineString' then
  541. return geoc_gcj02towgs84_line(geom);
  542. when 'ST_MultiLineString' then
  543. return geoc_gcj02towgs84_multiline(geom);
  544. when 'ST_Point' then
  545. return geoc_gcj02towgs84_point(geom);
  546. when 'ST_MultiPoint' then
  547. return geoc_gcj02towgs84_multipoint(geom);
  548. when 'ST_Polygon' then
  549. return geoc_gcj02towgs84_polygon(geom);
  550. when 'ST_MultiPolygon' then
  551. return geoc_gcj02towgs84_multipolygon(geom);
  552. ELSE
  553. RETURN null;
  554. END CASE;
  555. END;
  556. $BODY$
  557. LANGUAGE plpgsql VOLATILE
  558. COST 100;
  559. CREATE OR REPLACE FUNCTION "public"."geoc_is_in_china_bbox"("lon" numeric, "lat" numeric)
  560. RETURNS "pg_catalog"."bool" AS $BODY$
  561. DECLARE
  562. BEGIN
  563. return lon >= 72.004 and lon <= 137.8347 and lat >= 0.8293 and lat <= 55.8271;
  564. END;
  565. $BODY$
  566. LANGUAGE plpgsql VOLATILE
  567. COST 100;
  568. CREATE OR REPLACE FUNCTION "public"."geoc_transform_lat"("x" numeric, "y" numeric)
  569. RETURNS "pg_catalog"."numeric" AS $BODY$
  570. DECLARE
  571. ret numeric;
  572. BEGIN
  573. ret := -100 + 2 * x + 3 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(abs(x));
  574. ret := ret + (20 * sin(6 * x * PI()) + 20 * sin(2 * x * PI())) * 2 / 3;
  575. ret := ret +(20 * sin(y * PI()) + 40 * sin(y / 3 * PI())) * 2 / 3;
  576. ret := ret +(160 * sin(y / 12 * PI()) + 320 * sin(y * PI() / 30)) * 2 / 3;
  577. return ret;
  578. END;
  579. $BODY$
  580. LANGUAGE plpgsql VOLATILE
  581. COST 100;
  582. CREATE OR REPLACE FUNCTION "public"."geoc_transform_lon"("x" numeric, "y" numeric)
  583. RETURNS "pg_catalog"."numeric" AS $BODY$
  584. DECLARE
  585. ret numeric;
  586. BEGIN
  587. ret := 300 + x + 2 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(abs(x));
  588. ret :=ret + (20 * sin(6 * x * pi()) + 20 * sin(2 * x * pi())) * 2 / 3;
  589. ret :=ret + (20 * sin(x * pi()) + 40 * sin(x / 3 * pi())) * 2 / 3;
  590. ret :=ret + (150 * sin(x / 12 * pi()) + 300 * sin(x / 30 * pi())) * 2 / 3;
  591. return ret;
  592. END;
  593. $BODY$
  594. LANGUAGE plpgsql VOLATILE
  595. COST 100;
  596. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02_line"("geom" "public"."geometry")
  597. RETURNS "public"."geometry" AS $BODY$
  598. DECLARE
  599. p_p geometry;
  600. p_t geometry;
  601. z_t geometry;
  602. i int;
  603. BEGIN
  604. i:=1;
  605. while i <= st_npoints(geom) LOOP
  606. p_p := st_pointn(geom,i);
  607. p_t := geoc_wgs84togcj02_point(p_p);
  608. geom:=st_setpoint(geom,i-1,p_t);
  609. i:=i+1;
  610. end LOOP;
  611. return geom;
  612. END;
  613. $BODY$
  614. LANGUAGE plpgsql VOLATILE
  615. COST 100;
  616. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02_multiline"("geom" "public"."geometry")
  617. RETURNS "public"."geometry" AS $BODY$
  618. DECLARE
  619. i geometry;
  620. transform_i geometry;
  621. multiArr geometry[];
  622. BEGIN
  623. multiArr:='{}'::geometry[];
  624. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  625. transform_i :=geoc_wgs84togcj02_line(i);
  626. multiArr := array_append(multiArr, transform_i);
  627. end LOOP;
  628. return st_multi(ST_Union(multiArr));
  629. END;
  630. $BODY$
  631. LANGUAGE plpgsql VOLATILE
  632. COST 100;
  633. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02_multipoint"("geom" "public"."geometry")
  634. RETURNS "public"."geometry" AS $BODY$
  635. DECLARE
  636. i geometry;
  637. transform_i geometry;
  638. multiArr geometry[];
  639. BEGIN
  640. multiArr:='{}'::geometry[];
  641. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  642. transform_i :=geoc_wgs84togcj02_point(i);
  643. multiArr := array_append(multiArr, transform_i);
  644. end LOOP;
  645. return st_multi(ST_Union(multiArr));
  646. END;
  647. $BODY$
  648. LANGUAGE plpgsql VOLATILE
  649. COST 100;
  650. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02_multipolygon"("source_geom" "public"."geometry")
  651. RETURNS "public"."geometry" AS $BODY$
  652. DECLARE
  653. target_parts geometry[];
  654. single_polygon geometry;
  655. single_polygon_trans geometry;
  656. final_geom geometry;
  657. BEGIN
  658. IF ST_GeometryType(source_geom) != 'ST_MultiPolygon' THEN
  659. RETURN source_geom;
  660. END IF;
  661. FOR single_polygon IN SELECT (ST_Dump($1)).geom LOOP
  662. single_polygon_trans := geoc_wgs84togcj02_polygon(single_polygon);
  663. target_parts := array_append(target_parts,single_polygon_trans);
  664. END LOOP;
  665. SELECT st_multi(ST_Union(target_parts)) INTO final_geom;
  666. raise NOTICE 'final_geom: %',final_geom;
  667. RETURN final_geom;
  668. END;
  669. $BODY$
  670. LANGUAGE plpgsql VOLATILE
  671. COST 100;
  672. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02_polygon"("source_geom" "public"."geometry")
  673. RETURNS "public"."geometry" AS $BODY$
  674. DECLARE
  675. target_parts geometry[];
  676. source_npoints integer;
  677. single_line geometry;
  678. single_line_trans geometry;
  679. single_polygon geometry;
  680. final_geom geometry;
  681. BEGIN
  682. IF ST_GeometryType(source_geom) != 'ST_Polygon' THEN
  683. RETURN source_geom;
  684. END IF;
  685. FOR single_polygon IN SELECT ST_ExteriorRing ((st_dumprings($1)).geom) as geom LOOP
  686. source_npoints := ST_NPoints(single_polygon);
  687. single_line := ST_RemovePoint(single_polygon, source_npoints - 1);
  688. single_line_trans := geoc_wgs84togcj02_line(single_line);
  689. target_parts := array_append(target_parts, ST_AddPoint(single_line_trans, ST_PointN(single_line_trans, 1)));
  690. END LOOP;
  691. SELECT ST_MakePolygon(target_parts[1], target_parts[2:array_upper(target_parts, 1)]) INTO final_geom;
  692. -- raise NOTICE 'final_geom: %',final_geom;
  693. RETURN final_geom;
  694. END;
  695. $BODY$
  696. LANGUAGE plpgsql VOLATILE
  697. COST 100;
  698. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02"("coord" _numeric)
  699. RETURNS "pg_catalog"."_numeric" AS $BODY$
  700. DECLARE
  701. ret numeric[];
  702. dLon numeric;
  703. dlat numeric;
  704. lon numeric;
  705. lat numeric;
  706. d jsonb;
  707. -- coord ARRAY;
  708. BEGIN
  709. lon := coord[1];
  710. lat := coord[2];
  711. if (geoc_is_in_china_bbox(lon, lat) = false) then
  712. return coord;
  713. end if;
  714. d := geoc_delta(lon, lat);
  715. dlon := d->0;
  716. dlat := d->1;
  717. ret := ARRAY[lon + dlon , lat + dlat];
  718. return ret;
  719. END;
  720. $BODY$
  721. LANGUAGE plpgsql VOLATILE
  722. COST 100;
  723. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02_point"("geom" "public"."geometry")
  724. RETURNS "public"."geometry" AS $BODY$
  725. DECLARE
  726. lon numeric;
  727. lat numeric;
  728. d jsonb;
  729. dlon numeric;
  730. dlat numeric;
  731. BEGIN
  732. if st_geometrytype(geom) != 'ST_Point' then
  733. return geom;
  734. end if;
  735. lon := st_x(geom);
  736. lat := st_y(geom);
  737. if (geoc_is_in_china_bbox(lon, lat) = false) then
  738. return geom;
  739. end if;
  740. d := geoc_delta(lon, lat);
  741. dlon := d->0;
  742. dlat := d->1;
  743. return st_makepoint(lon + dlon,lat + dlat);
  744. END;
  745. $BODY$
  746. LANGUAGE plpgsql VOLATILE
  747. COST 100;
  748. CREATE OR REPLACE FUNCTION "public"."geoc_wgs84togcj02"("geom" "public"."geometry")
  749. RETURNS "public"."geometry" AS $BODY$
  750. DECLARE
  751. i geometry;
  752. transform_i geometry;
  753. multiArr geometry[];
  754. BEGIN
  755. IF st_srid(geom) != 4490 and st_srid(geom) != 4326 THEN
  756. RETURN null;
  757. end if;
  758. CASE ST_GeometryType(geom)
  759. when 'ST_LineString' then
  760. return geoc_wgs84togcj02_line(geom);
  761. when 'ST_MultiLineString' then
  762. return geoc_wgs84togcj02_multiline(geom);
  763. when 'ST_Point' then
  764. return geoc_wgs84togcj02_point(geom);
  765. when 'ST_MultiPoint' then
  766. return geoc_wgs84togcj02_multipoint(geom);
  767. when 'ST_Polygon' then
  768. return geoc_wgs84togcj02_polygon(geom);
  769. when 'ST_MultiPolygon' then
  770. return geoc_wgs84togcj02_multipolygon(geom);
  771. ELSE
  772. RETURN null;
  773. END CASE;
  774. END;
  775. $BODY$
  776. LANGUAGE plpgsql VOLATILE
  777. COST 100;
  778. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02towgs84_polygon"("source_geom" "public"."geometry")
  779. RETURNS "public"."geometry" AS $BODY$
  780. DECLARE
  781. target_parts geometry[];
  782. source_npoints integer;
  783. single_line geometry;
  784. single_line_trans geometry;
  785. single_polygon geometry;
  786. final_geom geometry;
  787. BEGIN
  788. IF ST_GeometryType(source_geom) != 'ST_Polygon' THEN
  789. RETURN null;
  790. END IF;
  791. FOR single_polygon IN SELECT ST_ExteriorRing ((st_dumprings($1)).geom) as geom LOOP
  792. source_npoints := ST_NPoints(single_polygon);
  793. single_line := ST_RemovePoint(single_polygon, source_npoints - 1);
  794. single_line_trans := geoc_gcj02towgs84_line(single_line);
  795. target_parts := array_append(target_parts, ST_AddPoint(single_line_trans, ST_PointN(single_line_trans, 1)));
  796. END LOOP;
  797. SELECT ST_MakePolygon(target_parts[1], target_parts[2:array_upper(target_parts, 1)]) INTO final_geom;
  798. -- raise NOTICE 'final_geom: %',final_geom;
  799. RETURN final_geom;
  800. END;
  801. $BODY$
  802. LANGUAGE plpgsql VOLATILE
  803. COST 100;
  804. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02towgs84_point"("geom" "public"."geometry")
  805. RETURNS "public"."geometry" AS $BODY$
  806. DECLARE
  807. tempPoint numeric[];
  808. wgsLon numeric;
  809. wgsLat numeric;
  810. lon numeric;
  811. lat numeric;
  812. BEGIN
  813. if st_geometrytype(geom) != 'ST_Point' then
  814. return null;
  815. end if;
  816. lon := st_x(geom);
  817. lat := st_y(geom);
  818. if geoc_is_in_china_bbox(lon, lat) = false THEN
  819. return geom;
  820. end if;
  821. tempPoint := geoc_wgs84togcj02(ARRAY[lon, lat]);
  822. wgsLon := lon*2 - tempPoint[1];
  823. wgsLat := lat*2 - tempPoint[2];
  824. return st_makepoint(wgsLon,wgsLat);
  825. END;
  826. $BODY$
  827. LANGUAGE plpgsql VOLATILE
  828. COST 100;
  829. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02towgs84_multipolygon"("source_geom" "public"."geometry")
  830. RETURNS "public"."geometry" AS $BODY$
  831. DECLARE
  832. target_parts geometry[];
  833. single_polygon geometry;
  834. single_polygon_trans geometry;
  835. final_geom geometry;
  836. BEGIN
  837. IF ST_GeometryType(source_geom) != 'ST_MultiPolygon' THEN
  838. RETURN null;
  839. END IF;
  840. FOR single_polygon IN SELECT (ST_Dump($1)).geom LOOP
  841. single_polygon_trans := geoc_gcj02towgs84_polygon(single_polygon);
  842. target_parts := array_append(target_parts,single_polygon_trans);
  843. END LOOP;
  844. SELECT st_multi(ST_Union(target_parts)) INTO final_geom;
  845. raise NOTICE 'final_geom: %',final_geom;
  846. RETURN final_geom;
  847. END;
  848. $BODY$
  849. LANGUAGE plpgsql VOLATILE
  850. COST 100;
  851. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02towgs84_multipoint"("geom" "public"."geometry")
  852. RETURNS "public"."geometry" AS $BODY$
  853. DECLARE
  854. i geometry;
  855. transform_i geometry;
  856. multiArr geometry[];
  857. BEGIN
  858. multiArr:='{}'::geometry[];
  859. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  860. transform_i :=geoc_gcj02towgs84_point(i);
  861. multiArr := array_append(multiArr, transform_i);
  862. end LOOP;
  863. return st_multi(ST_Union(multiArr));
  864. END;
  865. $BODY$
  866. LANGUAGE plpgsql VOLATILE
  867. COST 100;
  868. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02towgs84_multiline"("geom" "public"."geometry")
  869. RETURNS "public"."geometry" AS $BODY$
  870. DECLARE
  871. i geometry;
  872. transform_i geometry;
  873. multiArr geometry[];
  874. BEGIN
  875. multiArr:='{}'::geometry[];
  876. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  877. transform_i :=geoc_gcj02towgs84_line(i);
  878. multiArr := array_append(multiArr, transform_i);
  879. end LOOP;
  880. return st_multi(ST_Union(multiArr));
  881. END;
  882. $BODY$
  883. LANGUAGE plpgsql VOLATILE
  884. COST 100;
  885. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02towgs84_line"("geom" "public"."geometry")
  886. RETURNS "public"."geometry" AS $BODY$
  887. DECLARE
  888. p_p geometry;
  889. p_t geometry;
  890. z_t geometry;
  891. i int;
  892. BEGIN
  893. i:=1;
  894. while i <= st_npoints(geom) LOOP
  895. p_p := st_pointn(geom,i);
  896. p_t := geoc_gcj02towgs84_point(p_p);
  897. geom:=st_setpoint(geom,i-1,p_t);
  898. i:=i+1;
  899. end LOOP;
  900. return geom;
  901. END;
  902. $BODY$
  903. LANGUAGE plpgsql VOLATILE
  904. COST 100;
  905. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02towgs84"("geom" "public"."geometry")
  906. RETURNS "public"."geometry" AS $BODY$
  907. DECLARE
  908. BEGIN
  909. IF st_srid(geom) != 4490 and st_srid(geom) != 4326 THEN
  910. RETURN null;
  911. end if;
  912. case ST_GeometryType(geom)
  913. when 'ST_LineString' then
  914. return geoc_gcj02towgs84_line(geom);
  915. when 'ST_MultiLineString' then
  916. return geoc_gcj02towgs84_multiline(geom);
  917. when 'ST_Point' then
  918. return geoc_gcj02towgs84_point(geom);
  919. when 'ST_MultiPoint' then
  920. return geoc_gcj02towgs84_multipoint(geom);
  921. when 'ST_Polygon' then
  922. return geoc_gcj02towgs84_polygon(geom);
  923. when 'ST_MultiPolygon' then
  924. return geoc_gcj02towgs84_multipolygon(geom);
  925. ELSE
  926. RETURN null;
  927. END CASE;
  928. END;
  929. $BODY$
  930. LANGUAGE plpgsql VOLATILE
  931. COST 100;
  932. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02tobd09_polygon"("source_geom" "public"."geometry")
  933. RETURNS "public"."geometry" AS $BODY$
  934. DECLARE
  935. target_parts geometry[];
  936. source_npoints integer;
  937. single_line geometry;
  938. single_line_trans geometry;
  939. single_polygon geometry;
  940. final_geom geometry;
  941. BEGIN
  942. IF ST_GeometryType(source_geom) != 'ST_Polygon' THEN
  943. RETURN null;
  944. END IF;
  945. FOR single_polygon IN SELECT ST_ExteriorRing ((st_dumprings($1)).geom) as geom LOOP
  946. source_npoints := ST_NPoints(single_polygon);
  947. single_line := ST_RemovePoint(single_polygon, source_npoints - 1);
  948. single_line_trans := geoc_gcj02tobd09_line(single_line);
  949. target_parts := array_append(target_parts, ST_AddPoint(single_line_trans, ST_PointN(single_line_trans, 1)));
  950. END LOOP;
  951. SELECT ST_MakePolygon(target_parts[1], target_parts[2:array_upper(target_parts, 1)]) INTO final_geom;
  952. -- raise NOTICE 'final_geom: %',final_geom;
  953. RETURN final_geom;
  954. END;
  955. $BODY$
  956. LANGUAGE plpgsql VOLATILE
  957. COST 100;
  958. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02tobd09_point"("geom" "public"."geometry")
  959. RETURNS "public"."geometry" AS $BODY$
  960. DECLARE
  961. z double precision;
  962. theta double precision;
  963. x_pi double precision:=3.14159265358979324 * 3000.0 / 180.0;
  964. lon numeric;
  965. lat numeric;
  966. bd_point geometry;
  967. BEGIN
  968. if st_geometrytype(geom) != 'ST_Point' then
  969. return null;
  970. end if;
  971. lon := st_x(geom);
  972. lat := st_y(geom);
  973. if geoc_is_in_china_bbox(lon, lat) = false THEN
  974. return geom;
  975. end if;
  976. z:= sqrt(power(lon,2) + power(lat,2)) + 0.00002 * sin(lat * x_pi);
  977. theta:= atan2(lat, lon) + 0.000003 * cos(lon * x_pi);
  978. bd_point:=ST_SetSRID(ST_MakePoint(z * cos(theta) + 0.0065,z * sin(theta) + 0.006),4326);
  979. return bd_point;
  980. END;
  981. $BODY$
  982. LANGUAGE plpgsql VOLATILE
  983. COST 100;
  984. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02tobd09_multipolygon"("source_geom" "public"."geometry")
  985. RETURNS "public"."geometry" AS $BODY$
  986. DECLARE
  987. target_parts geometry[];
  988. single_polygon geometry;
  989. single_polygon_trans geometry;
  990. final_geom geometry;
  991. BEGIN
  992. IF ST_GeometryType(source_geom) != 'ST_MultiPolygon' THEN
  993. RETURN null;
  994. END IF;
  995. FOR single_polygon IN SELECT (ST_Dump($1)).geom LOOP
  996. single_polygon_trans := geoc_gcj02tobd09_polygon(single_polygon);
  997. target_parts := array_append(target_parts,single_polygon_trans);
  998. END LOOP;
  999. SELECT st_multi(ST_Union(target_parts)) INTO final_geom;
  1000. raise NOTICE 'final_geom: %',final_geom;
  1001. RETURN final_geom;
  1002. END;
  1003. $BODY$
  1004. LANGUAGE plpgsql VOLATILE
  1005. COST 100;
  1006. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02tobd09_multipoint"("geom" "public"."geometry")
  1007. RETURNS "public"."geometry" AS $BODY$
  1008. DECLARE
  1009. i geometry;
  1010. transform_i geometry;
  1011. multiArr geometry[];
  1012. BEGIN
  1013. multiArr:='{}'::geometry[];
  1014. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  1015. transform_i :=geoc_gcj02tobd09_point(i);
  1016. multiArr := array_append(multiArr, transform_i);
  1017. end LOOP;
  1018. return st_multi(ST_Union(multiArr));
  1019. END;
  1020. $BODY$
  1021. LANGUAGE plpgsql VOLATILE
  1022. COST 100;
  1023. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02tobd09_multiline"("geom" "public"."geometry")
  1024. RETURNS "public"."geometry" AS $BODY$
  1025. DECLARE
  1026. i geometry;
  1027. transform_i geometry;
  1028. multiArr geometry[];
  1029. BEGIN
  1030. multiArr:='{}'::geometry[];
  1031. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  1032. transform_i :=geoc_gcj02tobd09_line(i);
  1033. multiArr := array_append(multiArr, transform_i);
  1034. end LOOP;
  1035. return st_multi(ST_Union(multiArr));
  1036. END;
  1037. $BODY$
  1038. LANGUAGE plpgsql VOLATILE
  1039. COST 100;
  1040. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02tobd09_line"("geom" "public"."geometry")
  1041. RETURNS "public"."geometry" AS $BODY$
  1042. DECLARE
  1043. p_p geometry;
  1044. p_t geometry;
  1045. z_t geometry;
  1046. i int;
  1047. BEGIN
  1048. i:=1;
  1049. while i <= st_npoints(geom) LOOP
  1050. p_p := st_pointn(geom,i);
  1051. p_t := geoc_gcj02tobd09_point(p_p);
  1052. geom:=st_setpoint(geom,i-1,p_t);
  1053. i:=i+1;
  1054. end LOOP;
  1055. return geom;
  1056. END;
  1057. $BODY$
  1058. LANGUAGE plpgsql VOLATILE
  1059. COST 100;
  1060. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02tobd09"("geom" "public"."geometry")
  1061. RETURNS "public"."geometry" AS $BODY$
  1062. DECLARE
  1063. BEGIN
  1064. -- IF st_srid(geom) != '4490' THEN
  1065. -- RETURN null;
  1066. -- end if;
  1067. -- IF st_srid(geom) != '4326' THEN
  1068. -- RETURN null;
  1069. -- end if;
  1070. case ST_GeometryType(geom)
  1071. when 'ST_LineString' then
  1072. return geoc_gcj02tobd09_line(geom);
  1073. when 'ST_MultiLineString' then
  1074. return geoc_gcj02tobd09_multiline(geom);
  1075. when 'ST_Point' then
  1076. return geoc_gcj02tobd09_point(geom);
  1077. when 'ST_MultiPoint' then
  1078. return geoc_gcj02tobd09_multipoint(geom);
  1079. when 'ST_Polygon' then
  1080. return geoc_gcj02tobd09_polygon(geom);
  1081. when 'ST_MultiPolygon' then
  1082. return geoc_gcj02tobd09_multipolygon(geom);
  1083. ELSE
  1084. RETURN null;
  1085. END CASE;
  1086. END;
  1087. $BODY$
  1088. LANGUAGE plpgsql VOLATILE
  1089. COST 100;
  1090. CREATE OR REPLACE FUNCTION "public"."geoc_delta"("lon" numeric, "lat" numeric)
  1091. RETURNS "pg_catalog"."jsonb" AS $BODY$
  1092. DECLARE
  1093. ret varchar;
  1094. dLon numeric;
  1095. dlat numeric;
  1096. radLat numeric;
  1097. magic numeric;
  1098. sqrtMagic numeric;
  1099. ee numeric;
  1100. a numeric;
  1101. BEGIN
  1102. ee := 0.006693421622965823;
  1103. a := 6378245;
  1104. dLon := geoc_transform_lon(lon - 105, lat - 35);
  1105. dLat := geoc_transform_lat(lon - 105, lat - 35);
  1106. --raise NOTICE 'dLon的值为: %',dLon;
  1107. --raise NOTICE 'dLat的值为: %',dLat;
  1108. radLat := lat / 180 * pi();
  1109. magic = sin(radLat);
  1110. magic = 1 - ee * magic * magic;
  1111. sqrtMagic := sqrt(magic);
  1112. dLon = (dLon * 180) / (a / sqrtMagic * cos(radLat) * pi());
  1113. dLat = (dLat * 180) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi());
  1114. ret :='['||dLon||','||dLat||']';
  1115. return ret::jsonb;
  1116. END;
  1117. $BODY$
  1118. LANGUAGE plpgsql VOLATILE
  1119. COST 100;
  1120. CREATE OR REPLACE FUNCTION "public"."geoc_bd09towgs84_polygon"("source_geom" "public"."geometry")
  1121. RETURNS "public"."geometry" AS $BODY$
  1122. DECLARE
  1123. target_parts geometry[];
  1124. source_npoints integer;
  1125. single_line geometry;
  1126. single_line_trans geometry;
  1127. single_polygon geometry;
  1128. final_geom geometry;
  1129. BEGIN
  1130. IF ST_GeometryType(source_geom) != 'ST_Polygon' THEN
  1131. RETURN null;
  1132. END IF;
  1133. FOR single_polygon IN SELECT ST_ExteriorRing ((st_dumprings($1)).geom) as geom LOOP
  1134. source_npoints := ST_NPoints(single_polygon);
  1135. single_line := ST_RemovePoint(single_polygon, source_npoints - 1);
  1136. single_line_trans := geoc_bd09towgs84_line(single_line);
  1137. target_parts := array_append(target_parts, ST_AddPoint(single_line_trans, ST_PointN(single_line_trans, 1)));
  1138. END LOOP;
  1139. SELECT ST_MakePolygon(target_parts[1], target_parts[2:array_upper(target_parts, 1)]) INTO final_geom;
  1140. -- raise NOTICE 'final_geom: %',final_geom;
  1141. RETURN final_geom;
  1142. END;
  1143. $BODY$
  1144. LANGUAGE plpgsql VOLATILE
  1145. COST 100;
  1146. CREATE OR REPLACE FUNCTION "public"."geoc_bd09towgs84_point"("geom" "public"."geometry")
  1147. RETURNS "public"."geometry" AS $BODY$
  1148. DECLARE
  1149. x numeric;
  1150. y numeric;
  1151. gcj_point geometry;
  1152. wgs_point geometry;
  1153. BEGIN
  1154. if st_geometrytype(geom) != 'ST_Point' then
  1155. return null;
  1156. end if;
  1157. x := st_x(geom);
  1158. y := st_y(geom);
  1159. if (geoc_is_in_china_bbox(x, y) = false) then
  1160. return geom;
  1161. end if;
  1162. gcj_point = geoc_bd09togcj02_point(geom);
  1163. wgs_point = geoc_gcj02towgs84_point(gcj_point);
  1164. return wgs_point;
  1165. END;
  1166. $BODY$
  1167. LANGUAGE plpgsql VOLATILE
  1168. COST 100;
  1169. CREATE OR REPLACE FUNCTION "public"."geoc_bd09towgs84_multipolygon"("source_geom" "public"."geometry")
  1170. RETURNS "public"."geometry" AS $BODY$
  1171. DECLARE
  1172. target_parts geometry[];
  1173. single_polygon geometry;
  1174. single_polygon_trans geometry;
  1175. final_geom geometry;
  1176. BEGIN
  1177. IF ST_GeometryType(source_geom) != 'ST_MultiPolygon' THEN
  1178. RETURN null;
  1179. END IF;
  1180. FOR single_polygon IN SELECT (ST_Dump($1)).geom LOOP
  1181. single_polygon_trans := geoc_bd09towgs84_polygon(single_polygon);
  1182. target_parts := array_append(target_parts,single_polygon_trans);
  1183. END LOOP;
  1184. SELECT st_multi(ST_Union(target_parts)) INTO final_geom;
  1185. raise NOTICE 'final_geom: %',final_geom;
  1186. RETURN final_geom;
  1187. END;
  1188. $BODY$
  1189. LANGUAGE plpgsql VOLATILE
  1190. COST 100;
  1191. CREATE OR REPLACE FUNCTION "public"."geoc_bd09towgs84_multipoint"("geom" "public"."geometry")
  1192. RETURNS "public"."geometry" AS $BODY$
  1193. DECLARE
  1194. i geometry;
  1195. transform_i geometry;
  1196. multiArr geometry[];
  1197. BEGIN
  1198. multiArr:='{}'::geometry[];
  1199. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  1200. transform_i :=geoc_bd09towgs84_point(i);
  1201. multiArr := array_append(multiArr, transform_i);
  1202. end LOOP;
  1203. return st_multi(ST_Union(multiArr));
  1204. END;
  1205. $BODY$
  1206. LANGUAGE plpgsql VOLATILE
  1207. COST 100;
  1208. CREATE OR REPLACE FUNCTION "public"."geoc_bd09towgs84_multiline"("geom" "public"."geometry")
  1209. RETURNS "public"."geometry" AS $BODY$
  1210. DECLARE
  1211. i geometry;
  1212. transform_i geometry;
  1213. multiArr geometry[];
  1214. BEGIN
  1215. multiArr:='{}'::geometry[];
  1216. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  1217. transform_i :=geoc_bd09towgs84_line(i);
  1218. multiArr := array_append(multiArr, transform_i);
  1219. end LOOP;
  1220. return st_multi(ST_Union(multiArr));
  1221. END;
  1222. $BODY$
  1223. LANGUAGE plpgsql VOLATILE
  1224. COST 100;
  1225. CREATE OR REPLACE FUNCTION "public"."geoc_bd09towgs84_line"("geom" "public"."geometry")
  1226. RETURNS "public"."geometry" AS $BODY$
  1227. DECLARE
  1228. p_p geometry;
  1229. p_t geometry;
  1230. z_t geometry;
  1231. i int;
  1232. BEGIN
  1233. i:=1;
  1234. while i <= st_npoints(geom) LOOP
  1235. p_p := st_pointn(geom,i);
  1236. p_t := geoc_bd09towgs84_point(p_p);
  1237. geom:=st_setpoint(geom,i-1,p_t);
  1238. i:=i+1;
  1239. end LOOP;
  1240. return geom;
  1241. END;
  1242. $BODY$
  1243. LANGUAGE plpgsql VOLATILE
  1244. COST 100;
  1245. CREATE OR REPLACE FUNCTION "public"."geoc_bd09towgs84"("geom" "public"."geometry")
  1246. RETURNS "public"."geometry" AS $BODY$
  1247. DECLARE
  1248. i geometry;
  1249. transform_i geometry;
  1250. multiArr geometry[];
  1251. BEGIN
  1252. -- IF st_srid(geom) != '4490' THEN
  1253. -- RETURN geom;
  1254. -- end if;
  1255. -- IF st_srid(geom) != '4326' THEN
  1256. -- RETURN geom;
  1257. -- end if;
  1258. CASE ST_GeometryType(geom)
  1259. when 'ST_LineString' then
  1260. return geoc_bd09towgs84_line(geom);
  1261. when 'ST_MultiLineString' then
  1262. return geoc_bd09towgs84_multiline(geom);
  1263. when 'ST_Point' then
  1264. return geoc_bd09towgs84_point(geom);
  1265. when 'ST_MultiPoint' then
  1266. return geoc_bd09towgs84_multipoint(geom);
  1267. when 'ST_Polygon' then
  1268. return geoc_bd09towgs84_polygon(geom);
  1269. when 'ST_MultiPolygon' then
  1270. return geoc_bd09towgs84_multipolygon(geom);
  1271. ELSE
  1272. RETURN null;
  1273. END CASE;
  1274. END;
  1275. $BODY$
  1276. LANGUAGE plpgsql VOLATILE
  1277. COST 100;
  1278. CREATE OR REPLACE FUNCTION "public"."geoc_bd09togcj02_polygon"("source_geom" "public"."geometry")
  1279. RETURNS "public"."geometry" AS $BODY$
  1280. DECLARE
  1281. target_parts geometry[];
  1282. source_npoints integer;
  1283. single_line geometry;
  1284. single_line_trans geometry;
  1285. single_polygon geometry;
  1286. final_geom geometry;
  1287. BEGIN
  1288. IF ST_GeometryType(source_geom) != 'ST_Polygon' THEN
  1289. RETURN null;
  1290. END IF;
  1291. FOR single_polygon IN SELECT ST_ExteriorRing ((st_dumprings($1)).geom) as geom LOOP
  1292. source_npoints := ST_NPoints(single_polygon);
  1293. single_line := ST_RemovePoint(single_polygon, source_npoints - 1);
  1294. single_line_trans := geoc_bd09togcj02_line(single_line);
  1295. target_parts := array_append(target_parts, ST_AddPoint(single_line_trans, ST_PointN(single_line_trans, 1)));
  1296. END LOOP;
  1297. SELECT ST_MakePolygon(target_parts[1], target_parts[2:array_upper(target_parts, 1)]) INTO final_geom;
  1298. -- raise NOTICE 'final_geom: %',final_geom;
  1299. RETURN final_geom;
  1300. END;
  1301. $BODY$
  1302. LANGUAGE plpgsql VOLATILE
  1303. COST 100;
  1304. CREATE OR REPLACE FUNCTION "public"."geoc_bd09togcj02_point"("geom" "public"."geometry")
  1305. RETURNS "public"."geometry" AS $BODY$
  1306. DECLARE
  1307. x numeric;
  1308. y numeric;
  1309. z double precision;
  1310. theta double precision;
  1311. x_pi double precision:=3.14159265358979324 * 3000.0 / 180.0;
  1312. gcj_point geometry;
  1313. BEGIN
  1314. if st_geometrytype(geom) != 'ST_Point' then
  1315. return null;
  1316. end if;
  1317. x := st_x(geom);
  1318. y := st_y(geom);
  1319. if (geoc_is_in_china_bbox(x, y) = false) then
  1320. return geom;
  1321. end if;
  1322. x:= ST_X(geom) - 0.0065;
  1323. y:= ST_Y(geom) - 0.006;
  1324. z:=sqrt(power(x,2) + power(y,2)) - 0.00002 *sin(y * x_pi);
  1325. theta:= atan2(y, x) - 0.000003 * cos(x * x_pi);
  1326. gcj_point:=ST_SetSRID(ST_MakePoint(z *cos(theta),z *sin(theta)),4326);
  1327. return gcj_point;
  1328. END;
  1329. $BODY$
  1330. LANGUAGE plpgsql VOLATILE
  1331. COST 100;
  1332. CREATE OR REPLACE FUNCTION "public"."geoc_bd09togcj02_multipolygon"("source_geom" "public"."geometry")
  1333. RETURNS "public"."geometry" AS $BODY$
  1334. DECLARE
  1335. target_parts geometry[];
  1336. single_polygon geometry;
  1337. single_polygon_trans geometry;
  1338. final_geom geometry;
  1339. BEGIN
  1340. IF ST_GeometryType(source_geom) != 'ST_MultiPolygon' THEN
  1341. RETURN null;
  1342. END IF;
  1343. FOR single_polygon IN SELECT (ST_Dump($1)).geom LOOP
  1344. single_polygon_trans := geoc_bd09togcj02_polygon(single_polygon);
  1345. target_parts := array_append(target_parts,single_polygon_trans);
  1346. END LOOP;
  1347. SELECT st_multi(ST_Union(target_parts)) INTO final_geom;
  1348. raise NOTICE 'final_geom: %',final_geom;
  1349. RETURN final_geom;
  1350. END;
  1351. $BODY$
  1352. LANGUAGE plpgsql VOLATILE
  1353. COST 100;
  1354. CREATE OR REPLACE FUNCTION "public"."geoc_bd09togcj02_multipoint"("geom" "public"."geometry")
  1355. RETURNS "public"."geometry" AS $BODY$
  1356. DECLARE
  1357. i geometry;
  1358. transform_i geometry;
  1359. multiArr geometry[];
  1360. BEGIN
  1361. multiArr:='{}'::geometry[];
  1362. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  1363. transform_i :=geoc_bd09togcj02_point(i);
  1364. multiArr := array_append(multiArr, transform_i);
  1365. end LOOP;
  1366. return st_multi(ST_Union(multiArr));
  1367. END;
  1368. $BODY$
  1369. LANGUAGE plpgsql VOLATILE
  1370. COST 100;
  1371. CREATE OR REPLACE FUNCTION "public"."geoc_bd09togcj02_multiline"("geom" "public"."geometry")
  1372. RETURNS "public"."geometry" AS $BODY$
  1373. DECLARE
  1374. i geometry;
  1375. transform_i geometry;
  1376. multiArr geometry[];
  1377. BEGIN
  1378. multiArr:='{}'::geometry[];
  1379. for i in EXECUTE $Q$ select (st_dump($1)).geom $Q$ using geom LOOP
  1380. transform_i :=geoc_bd09togcj02_line(i);
  1381. multiArr := array_append(multiArr, transform_i);
  1382. end LOOP;
  1383. return st_multi(ST_Union(multiArr));
  1384. END;
  1385. $BODY$
  1386. LANGUAGE plpgsql VOLATILE
  1387. COST 100;
  1388. CREATE OR REPLACE FUNCTION "public"."geoc_bd09togcj02_line"("geom" "public"."geometry")
  1389. RETURNS "public"."geometry" AS $BODY$
  1390. DECLARE
  1391. p_p geometry;
  1392. p_t geometry;
  1393. z_t geometry;
  1394. i int;
  1395. BEGIN
  1396. i:=1;
  1397. while i <= st_npoints(geom) LOOP
  1398. p_p := st_pointn(geom,i);
  1399. p_t := geoc_bd09togcj02_point(p_p);
  1400. geom:=st_setpoint(geom,i-1,p_t);
  1401. i:=i+1;
  1402. end LOOP;
  1403. return geom;
  1404. END;
  1405. $BODY$
  1406. LANGUAGE plpgsql VOLATILE
  1407. COST 100;
  1408. CREATE OR REPLACE FUNCTION "public"."geoc_bd09togcj02"("geom" "public"."geometry")
  1409. RETURNS "public"."geometry" AS $BODY$
  1410. DECLARE
  1411. i geometry;
  1412. transform_i geometry;
  1413. multiArr geometry[];
  1414. BEGIN
  1415. -- IF st_srid(geom) != '4490' THEN
  1416. -- RETURN geom;
  1417. -- end if;
  1418. -- IF st_srid(geom) != '4326' THEN
  1419. -- RETURN geom;
  1420. -- end if;
  1421. CASE ST_GeometryType(geom)
  1422. when 'ST_LineString' then
  1423. return geoc_bd09togcj02_line(geom);
  1424. when 'ST_MultiLineString' then
  1425. return geoc_bd09togcj02_multiline(geom);
  1426. when 'ST_Point' then
  1427. return geoc_bd09togcj02_point(geom);
  1428. when 'ST_MultiPoint' then
  1429. return geoc_bd09togcj02_multipoint(geom);
  1430. when 'ST_Polygon' then
  1431. return geoc_bd09togcj02_polygon(geom);
  1432. when 'ST_MultiPolygon' then
  1433. return geoc_bd09togcj02_multipolygon(geom);
  1434. ELSE
  1435. RETURN null;
  1436. END CASE;
  1437. END;
  1438. $BODY$
  1439. LANGUAGE plpgsql VOLATILE
  1440. COST 100;
  1441. CREATE OR REPLACE FUNCTION "public"."geoc_cgcs2000togcj02"("geom" "public"."geometry")
  1442. RETURNS "public"."geometry" AS $BODY$
  1443. DECLARE
  1444. BEGIN
  1445. IF st_srid(geom) != '4490' THEN
  1446. RETURN null;
  1447. end if;
  1448. return geoc_wgs84togcj02(st_transform(st_setsrid(geom,4490),4326));
  1449. END;
  1450. $BODY$
  1451. LANGUAGE plpgsql VOLATILE
  1452. COST 100;
  1453. CREATE OR REPLACE FUNCTION "public"."geoc_cgcs2000tobd09"("geom" "public"."geometry")
  1454. RETURNS "public"."geometry" AS $BODY$
  1455. DECLARE
  1456. BEGIN
  1457. IF st_srid(geom) != '4490' THEN
  1458. RETURN null;
  1459. end if;
  1460. return geoc_wgs84tobd09(st_transform(st_setsrid(geom,4490),4326));
  1461. END;
  1462. $BODY$
  1463. LANGUAGE plpgsql VOLATILE
  1464. COST 100;
  1465. CREATE OR REPLACE FUNCTION "public"."geoc_bd09tocgcs2000"("geom" "public"."geometry")
  1466. RETURNS "public"."geometry" AS $BODY$
  1467. DECLARE
  1468. BEGIN
  1469. IF st_srid(geom) != '4490' THEN
  1470. RETURN null;
  1471. end if;
  1472. return st_transform(st_setsrid(geoc_bd09towgs84(geom),4326),4490);
  1473. END;
  1474. $BODY$
  1475. LANGUAGE plpgsql VOLATILE
  1476. COST 100;
  1477. CREATE OR REPLACE FUNCTION "public"."geoc_gcj02tocgcs2000"("geom" "public"."geometry")
  1478. RETURNS "public"."geometry" AS $BODY$
  1479. DECLARE
  1480. BEGIN
  1481. IF st_srid(geom) != '4490' THEN
  1482. RETURN null;
  1483. end if;
  1484. return st_transform(st_setsrid(geoc_gcj02towgs84(geom),4326),4490);
  1485. END;
  1486. $BODY$
  1487. LANGUAGE plpgsql VOLATILE
  1488. COST 100