PageRenderTime 50ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/trunk/source/Common/EWKBtoGDO.cpp

#
C++ | 2274 lines | 1934 code | 279 blank | 61 comment | 171 complexity | 6b2812684c318001f2bee8be1bdb96e5 MD5 | raw file
Possible License(s): Apache-2.0

Large files files are truncated, but you can click here to view the full file

  1. // Copyright 2011 Intergraph Corporation
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "EWKBtoGDO.hpp"
  15. #include <math.h>
  16. #include "PGSTypes.hpp"
  17. #include "../Common/LogFiles.hpp"
  18. #include <stdio.h>
  19. unsigned char GetByte(unsigned char **psBuf, int *piCurLen)
  20. {
  21. unsigned char ucRes = **psBuf;
  22. (*psBuf)++;
  23. (*piCurLen)++;
  24. return(ucRes);
  25. }
  26. unsigned long GetGeomType(unsigned char **psBuf, unsigned char uiByteOrder,
  27. int *piCurLen)
  28. {
  29. unsigned long ulRes = 0;
  30. unsigned char *pbyte = (unsigned char*)&ulRes;
  31. if(uiByteOrder)
  32. {
  33. for(int i = 0; i < 4; i++) pbyte[i] = GetByte(psBuf, piCurLen);
  34. }
  35. else
  36. {
  37. for(int i = 0; i < 4; i++) pbyte[3 - i] = GetByte(psBuf, piCurLen);
  38. }
  39. // EWKB has a strange last byte, containing what? Dimension?
  40. pbyte[3] = 0;
  41. return(ulRes);
  42. }
  43. unsigned long GetLong(unsigned char **psBuf, unsigned char uiByteOrder,
  44. int *piCurLen)
  45. {
  46. unsigned long ulRes = 0;
  47. unsigned char *pbyte = (unsigned char*)&ulRes;
  48. if(uiByteOrder)
  49. {
  50. for(int i = 0; i < 4; i++) pbyte[i] = GetByte(psBuf, piCurLen);
  51. }
  52. else
  53. {
  54. for(int i = 0; i < 4; i++) pbyte[3 - i] = GetByte(psBuf, piCurLen);
  55. }
  56. return(ulRes);
  57. }
  58. double GetDouble(unsigned char **psBuf, unsigned char uiByteOrder, int *piCurLen)
  59. {
  60. double dblRes = 0;
  61. unsigned char *pbyte = (unsigned char*)&dblRes;
  62. if(uiByteOrder)
  63. {
  64. for(int i = 0; i < 8; i++) pbyte[i] = GetByte(psBuf, piCurLen);
  65. }
  66. else
  67. {
  68. for(int i = 0; i < 8; i++) pbyte[7 - i] = GetByte(psBuf, piCurLen);
  69. }
  70. return(dblRes);
  71. }
  72. void GetTriple(unsigned char **psBuf, unsigned char ucByteOrder, int iDim,
  73. int *piCurLen, double *px)
  74. {
  75. px[0] = GetDouble(psBuf, ucByteOrder, piCurLen);
  76. px[1] = GetDouble(psBuf, ucByteOrder, piCurLen);
  77. if(iDim > 2)
  78. {
  79. px[2] = GetDouble(psBuf, ucByteOrder, piCurLen);
  80. if(_isnan(px[2])) px[2] = -9999.0;
  81. }
  82. else px[2] = 0.0;
  83. if(iDim > 3)
  84. {
  85. *psBuf += 8;
  86. *piCurLen += 8;
  87. }
  88. return;
  89. }
  90. int GetArcGeomSize(double *dStart, double *dMiddle, double *dEnd)
  91. {
  92. double dMag = (dEnd[0] - dStart[0])*(dEnd[0] - dStart[0]) +
  93. (dEnd[1] - dStart[1])*(dEnd[1] - dStart[1]) +
  94. (dEnd[2] - dStart[2])*(dEnd[2] - dStart[2]);
  95. double dPrec = gdPrecLim*sqrt(dMag);
  96. double alpha[3];
  97. alpha[0] = (dEnd[1] - dStart[1])*(dMiddle[2] - dStart[2]) -
  98. (dEnd[2] - dStart[2])*(dMiddle[1] - dStart[1]);
  99. alpha[1] = (dEnd[2] - dStart[2])*(dMiddle[0] - dStart[0]) -
  100. (dEnd[0] - dStart[0])*(dMiddle[2] - dStart[2]);
  101. alpha[2] = (dEnd[0] - dStart[0])*(dMiddle[1] - dStart[1]) -
  102. (dEnd[1] - dStart[1])*(dMiddle[0] - dStart[0]);
  103. if((fabs(alpha[0]) < dPrec) && (fabs(alpha[1]) < dPrec) &&
  104. (fabs(alpha[2]) < dPrec))
  105. {
  106. return(64);
  107. }
  108. double A[2][2];
  109. A[0][0] = 0.0;
  110. A[0][1] = 0.0;
  111. A[1][0] = 0.0;
  112. A[1][1] = 0.0;
  113. for(int i = 0; i < 3; i++)
  114. {
  115. A[0][0] += (dMiddle[i] - dStart[i])*(dMiddle[i] - dStart[i]);
  116. A[0][1] += (dMiddle[i] - dStart[i])*(dMiddle[i] - dEnd[i]);
  117. A[1][0] += (dMiddle[i] - dEnd[i])*(dMiddle[i] - dStart[i]);
  118. A[1][1] += (dMiddle[i] - dEnd[i])*(dMiddle[i] - dEnd[i]);
  119. }
  120. double D = A[0][0]*A[1][1] - A[0][1]*A[1][0];
  121. if(fabs(D) > dPrec) return(96); // arc geometry
  122. else return(64); // line geometry
  123. }
  124. unsigned char* WriteArcGeometry(unsigned char *pBuf, double *dStart,
  125. double *dMiddle, double *dEnd)
  126. {
  127. double dMag = (dEnd[0] - dStart[0])*(dEnd[0] - dStart[0]) +
  128. (dEnd[1] - dStart[1])*(dEnd[1] - dStart[1]) +
  129. (dEnd[2] - dStart[2])*(dEnd[2] - dStart[2]);
  130. double dPrec = gdPrecLim*sqrt(dMag);
  131. double alpha[3];
  132. alpha[0] = (dEnd[1] - dStart[1])*(dMiddle[2] - dStart[2]) -
  133. (dEnd[2] - dStart[2])*(dMiddle[1] - dStart[1]);
  134. alpha[1] = (dEnd[2] - dStart[2])*(dMiddle[0] - dStart[0]) -
  135. (dEnd[0] - dStart[0])*(dMiddle[2] - dStart[2]);
  136. alpha[2] = (dEnd[0] - dStart[0])*(dMiddle[1] - dStart[1]) -
  137. (dEnd[1] - dStart[1])*(dMiddle[0] - dStart[0]);
  138. if((fabs(alpha[0]) < dPrec) && (fabs(alpha[1]) < dPrec) &&
  139. (fabs(alpha[2]) < dPrec))
  140. {
  141. memcpy(pBuf, &GID_LineGeometry, 16);
  142. pBuf += 16;
  143. *(double*)pBuf = dStart[0];
  144. pBuf += 8;
  145. *(double*)pBuf = dStart[1];
  146. pBuf += 8;
  147. *(double*)pBuf = dStart[2];
  148. pBuf += 8;
  149. *(double*)pBuf = dEnd[0];
  150. pBuf += 8;
  151. *(double*)pBuf = dEnd[1];
  152. pBuf += 8;
  153. *(double*)pBuf = dEnd[2];
  154. pBuf += 8;
  155. return(pBuf);
  156. }
  157. double A[2][2], B[2];
  158. A[0][0] = 0.0;
  159. A[0][1] = 0.0;
  160. A[1][0] = 0.0;
  161. A[1][1] = 0.0;
  162. B[0] = 0.0;
  163. B[1] = 0.0;
  164. for(int i = 0; i < 3; i++)
  165. {
  166. A[0][0] += (dMiddle[i] - dStart[i])*(dMiddle[i] - dStart[i]);
  167. A[0][1] += (dMiddle[i] - dStart[i])*(dMiddle[i] - dEnd[i]);
  168. A[1][0] += (dMiddle[i] - dEnd[i])*(dMiddle[i] - dStart[i]);
  169. A[1][1] += (dMiddle[i] - dEnd[i])*(dMiddle[i] - dEnd[i]);
  170. B[0] += (dMiddle[i]*dMiddle[i] + dStart[i]*dStart[i])/2.0 -
  171. dMiddle[i]*dStart[i];
  172. B[1] += (dMiddle[i]*dMiddle[i] + dEnd[i]*dEnd[i])/2.0 -
  173. dMiddle[i]*dEnd[i];
  174. }
  175. double D = A[0][0]*A[1][1] - A[0][1]*A[1][0];
  176. if(fabs(D) > dPrec)
  177. {
  178. memcpy(pBuf, &GID_ArcGeometry, 16);
  179. pBuf += 16;
  180. *(double*)pBuf = dStart[0];
  181. pBuf += 8;
  182. *(double*)pBuf = dStart[1];
  183. pBuf += 8;
  184. *(double*)pBuf = dStart[2];
  185. pBuf += 8;
  186. *(double*)pBuf = dEnd[0];
  187. pBuf += 8;
  188. *(double*)pBuf = dEnd[1];
  189. pBuf += 8;
  190. *(double*)pBuf = dEnd[2];
  191. pBuf += 8;
  192. double gamma[2];
  193. gamma[0] = (A[1][1]*B[0] - A[0][1]*B[1])/D;
  194. gamma[1] = (A[0][0]*B[1] - A[1][0]*B[0])/D;
  195. double S[3];
  196. double r = 0.0;
  197. for(int i = 0; i < 3; i++)
  198. {
  199. //S[i] = sMiddle[i] + gamma[0]*(xStart[i] - xMiddle[i]) +
  200. // gamma[1]*(xEnd[i] - xMiddle[i]);
  201. //r += (sMiddle[i] - S[i])*(sMiddle[i] - S[i]);
  202. S[i] = gamma[0]*(dStart[i] - dMiddle[i]) +
  203. gamma[1]*(dEnd[i] - dMiddle[i]);
  204. r += S[i]*S[i];
  205. S[i] += dMiddle[i];
  206. }
  207. r = sqrt(r);
  208. double normal1[3], normal2[3], normal3[3];
  209. normal1[0] = (dStart[1] - S[1])*(dMiddle[2] - S[2]) -
  210. (dStart[2] - S[2])*(dMiddle[1] - S[1]);
  211. normal1[1] = (dStart[2] - S[2])*(dMiddle[0] - S[0]) -
  212. (dStart[0] - S[0])*(dMiddle[2] - S[2]);
  213. normal1[2] = (dStart[0] - S[0])*(dMiddle[1] - S[1]) -
  214. (dStart[1] - S[1])*(dMiddle[0] - S[0]);
  215. normal2[0] = (dMiddle[1] - S[1])*(dEnd[2] - S[2]) -
  216. (dMiddle[2] - S[2])*(dEnd[1] - S[1]);
  217. normal2[1] = (dMiddle[2] - S[2])*(dEnd[0] - S[0]) -
  218. (dMiddle[0] - S[0])*(dEnd[2] - S[2]);
  219. normal2[2] = (dMiddle[0] - S[0])*(dEnd[1] - S[1]) -
  220. (dMiddle[1] - S[1])*(dEnd[0] - S[0]);
  221. normal3[0] = (dStart[1] - S[1])*(dEnd[2] - S[2]) -
  222. (dStart[2] - S[2])*(dEnd[1] - S[1]);
  223. normal3[1] = (dStart[2] - S[2])*(dEnd[0] - S[0]) -
  224. (dStart[0] - S[0])*(dEnd[2] - S[2]);
  225. normal3[2] = (dStart[0] - S[0])*(dEnd[1] - S[1]) -
  226. (dStart[1] - S[1])*(dEnd[0] - S[0]);
  227. double norms[3];
  228. norms[0] = normal1[0]*normal1[0] + normal1[1]*normal1[1]
  229. + normal1[2]*normal1[2];
  230. norms[1] = normal2[0]*normal2[0] + normal2[1]*normal2[1]
  231. + normal2[2]*normal2[2];
  232. norms[2] = normal3[0]*normal3[0] + normal3[1]*normal3[1]
  233. + normal3[2]*normal3[2];
  234. int ori1 = GetOrient(normal1, normal2);
  235. if(ori1 > 0)
  236. {
  237. if(fabs(norms[1]) > fabs(norms[0]))
  238. {
  239. norms[1] = sqrt(norms[1]);
  240. *(double*)pBuf = normal2[0]/norms[1];
  241. pBuf += 8;
  242. *(double*)pBuf = normal2[1]/norms[1];
  243. pBuf += 8;
  244. *(double*)pBuf = normal2[2]/norms[1];
  245. pBuf += 8;
  246. }
  247. else
  248. {
  249. norms[0] = sqrt(norms[0]);
  250. *(double*)pBuf = normal1[0]/norms[0];
  251. pBuf += 8;
  252. *(double*)pBuf = normal1[1]/norms[0];
  253. pBuf += 8;
  254. *(double*)pBuf = normal1[2]/norms[0];
  255. pBuf += 8;
  256. }
  257. if((GetOrient(normal1, normal3) >= 0) &&
  258. (GetOrient(normal2, normal3) >= 0)) r = -r;
  259. }
  260. else
  261. {
  262. if(GetOrient(normal1, normal3) > 0)
  263. {
  264. norms[1] = sqrt(norms[1]);
  265. *(double*)pBuf = normal2[0]/norms[1];
  266. pBuf += 8;
  267. *(double*)pBuf = normal2[1]/norms[1];
  268. pBuf += 8;
  269. *(double*)pBuf = normal2[2]/norms[1];
  270. pBuf += 8;
  271. }
  272. else
  273. {
  274. norms[0] = sqrt(norms[0]);
  275. *(double*)pBuf = normal1[0]/norms[0];
  276. pBuf += 8;
  277. *(double*)pBuf = normal1[1]/norms[0];
  278. pBuf += 8;
  279. *(double*)pBuf = normal1[2]/norms[0];
  280. pBuf += 8;
  281. }
  282. }
  283. *(double*)pBuf = r;
  284. pBuf += 8;
  285. }
  286. else
  287. {
  288. memcpy(pBuf, &GID_LineGeometry, 16);
  289. pBuf += 16;
  290. *(double*)pBuf = dStart[0];
  291. pBuf += 8;
  292. *(double*)pBuf = dStart[1];
  293. pBuf += 8;
  294. *(double*)pBuf = dStart[2];
  295. pBuf += 8;
  296. *(double*)pBuf = dEnd[0];
  297. pBuf += 8;
  298. *(double*)pBuf = dEnd[1];
  299. pBuf += 8;
  300. *(double*)pBuf = dEnd[2];
  301. pBuf += 8;
  302. }
  303. return(pBuf);
  304. }
  305. int GetEWKBtoPointLen(unsigned char *sBuf, int iDim, long *plen,
  306. unsigned char ucByteOrder)
  307. {
  308. (*plen) += 16; // 16 bytes for Geom GUID
  309. (*plen) += 48; // 24 bytes for location, 24 bytes for orientation
  310. int iRes = 8*iDim;
  311. return(iRes);
  312. }
  313. int EWKBtoPoint(unsigned char *sBuf, unsigned char *pBuf, int iDim, long *plen,
  314. unsigned char ucByteOrder)
  315. {
  316. memcpy(pBuf, &GID_OrientedPointGeometry, 16);
  317. (*plen) += 16; // 16 bytes for Geom GUID
  318. pBuf += 16;
  319. (*plen) += 48; // 24 bytes for location, 24 bytes for orientation
  320. int iRes = 0;
  321. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, (double*)pBuf);
  322. pBuf += 24;
  323. *(double*)pBuf = 1.0;
  324. pBuf += 8;
  325. *(double*)pBuf = 0.0;
  326. pBuf += 8;
  327. *(double*)pBuf = 0.0;
  328. pBuf += 8;
  329. return(iRes);
  330. }
  331. int GetEWKBtoLineStringLen(unsigned char *sBuf, int iDim, long *plen,
  332. unsigned char ucByteOrder, bool bWriteGUID)
  333. {
  334. int iRes = 0;
  335. unsigned long ulLen = GetLong(&sBuf, ucByteOrder, &iRes);
  336. if(bWriteGUID)
  337. (*plen) += 20; // 16 bytes for Geom GUID, 4 bytes for num points
  338. (*plen) += ulLen*24; // 24 bytes for each 3 doubles
  339. iRes += ulLen*8*iDim;
  340. return(iRes);
  341. }
  342. int EWKBtoLineString(unsigned char *sBuf, unsigned char *pBuf, int iDim, long *plen,
  343. unsigned char ucByteOrder, unsigned long *plItemCount)
  344. {
  345. #if DBGLEVEL > 2
  346. WriteLogFile("EWKBtoLineString\r\n", true);
  347. #endif // DBGLEVEL
  348. int iRes = 0;
  349. unsigned long ulLen = GetLong(&sBuf, ucByteOrder, &iRes);
  350. if(plItemCount) (*plItemCount) += ulLen;
  351. else
  352. {
  353. memcpy(pBuf, &GID_PolylineGeometry, 16);
  354. pBuf += 16;
  355. *(unsigned long*)pBuf = ulLen;
  356. pBuf += 4;
  357. (*plen) += 20; // 16 bytes for Geom GUID, 4 bytes for num points
  358. }
  359. (*plen) += ulLen*24; // 24 bytes for each 3 doubles
  360. for(int i = 0; i < (int)ulLen; i++)
  361. {
  362. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, (double*)pBuf);
  363. pBuf += 24;
  364. }
  365. return(iRes);
  366. }
  367. int GetEWKBtoPolygonLen(unsigned char *sBuf, int iDim, long *plen,
  368. unsigned char ucByteOrder)
  369. {
  370. int iRes = 0;
  371. unsigned long ulLen = GetLong(&sBuf, ucByteOrder, &iRes);
  372. if(ulLen > 1) // boundary geometry
  373. {
  374. (*plen) += 16; // 16 bytes for Geom GUID
  375. unsigned long lulLen = GetLong(&sBuf, ucByteOrder, &iRes);
  376. int ilen = lulLen*8*iDim;
  377. // 4 bytes for boundary size, 16 bytes for polgon GUID,
  378. // 4 bytes for points count
  379. (*plen) += (24 + 24*lulLen);
  380. iRes += ilen;
  381. sBuf += ilen;
  382. // 4 bytes for collection size, 16 bytes for collection GUID,
  383. // 4 bytes for collection count
  384. (*plen) += 24;
  385. int i = 1;
  386. while(i < (int)ulLen)
  387. {
  388. lulLen = GetLong(&sBuf, ucByteOrder, &iRes);
  389. ilen = lulLen*8*iDim;
  390. // 4 bytes for polygon size, 16 bytes for polgon GUID,
  391. // 4 bytes for points count
  392. (*plen) += (24 + 24*lulLen);
  393. iRes += ilen;
  394. sBuf += ilen;
  395. i++;
  396. }
  397. }
  398. else if(ulLen == 1) // polygon geometry
  399. {
  400. (*plen) += 16; // 16 bytes for Geom GUID
  401. ulLen = GetLong(&sBuf, ucByteOrder, &iRes);
  402. (*plen) += (4 + ulLen*24); // 4 bytes for num points, 24 bytes for each 3 doubles
  403. iRes += ulLen*8*iDim;
  404. }
  405. return(iRes);
  406. }
  407. int EWKBtoPolygon(unsigned char *sBuf, unsigned char *pBuf, int iDim, long *plen,
  408. unsigned char ucByteOrder)
  409. {
  410. int iRes = 0;
  411. unsigned long ulLen = GetLong(&sBuf, ucByteOrder, &iRes);
  412. if(ulLen > 1) // boundary geometry
  413. {
  414. memcpy(pBuf, &GID_BoundaryGeometry, 16);
  415. pBuf += 16;
  416. (*plen) += 16; // 16 bytes for Geom GUID
  417. unsigned long lulLen = GetLong(&sBuf, ucByteOrder, &iRes);
  418. // 4 bytes for boundary size, 16 bytes for polgon GUID,
  419. // 4 bytes for points count
  420. *(unsigned long*)pBuf = (20 + 24*lulLen);
  421. pBuf += 4;
  422. (*plen) += (24 + 24*lulLen);
  423. memcpy(pBuf, &GID_PolygonGeometry, 16);
  424. pBuf += 16;
  425. *(unsigned long*)pBuf = lulLen;
  426. pBuf += 4;
  427. for(int j = 0; j < (int)lulLen; j++)
  428. {
  429. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, (double*)pBuf);
  430. pBuf += 24;
  431. }
  432. unsigned char *pSaveBuf = pBuf;
  433. pBuf += 4;
  434. memcpy(pBuf, &GID_GeometryCollection, 16);
  435. pBuf += 16;
  436. *(unsigned long*)pBuf = (ulLen - 1);
  437. pBuf += 4;
  438. unsigned long llsize = 20; // 16 bytes GUID, 4 bztes col count
  439. // 4 bytes for collection size, 16 bytes for collection GUID,
  440. // 4 bytes for collection count
  441. (*plen) += 24;
  442. int i = 1;
  443. while(i < (int)ulLen)
  444. {
  445. lulLen = GetLong(&sBuf, ucByteOrder, &iRes);
  446. // 4 bytes for polygon size, 16 bytes for polgon GUID,
  447. // 4 bytes for points count
  448. llsize += (24 + 24*lulLen);
  449. (*plen) += (24 + 24*lulLen);
  450. *(unsigned long*)pBuf = (20 + 24*lulLen);
  451. pBuf += 4;
  452. memcpy(pBuf, &GID_PolygonGeometry, 16);
  453. pBuf += 16;
  454. *(unsigned long*)pBuf = lulLen;
  455. pBuf += 4;
  456. for(int j = 0; j < (int)lulLen; j++)
  457. {
  458. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, (double*)pBuf);
  459. pBuf += 24;
  460. }
  461. i++;
  462. }
  463. *(unsigned long*)pSaveBuf = llsize;
  464. }
  465. else if(ulLen == 1) // polygon geometry
  466. {
  467. memcpy(pBuf, &GID_PolygonGeometry, 16);
  468. (*plen) += 16; // 16 bytes for Geom GUID
  469. pBuf += 16;
  470. ulLen = GetLong(&sBuf, ucByteOrder, &iRes);
  471. *(unsigned long*)pBuf = ulLen;
  472. pBuf += 4;
  473. (*plen) += (4 + ulLen*24); // 4 bytes for num points, 24 bytes for each 3 doubles
  474. for(int i = 0; i < (int)ulLen; i++)
  475. {
  476. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, (double*)pBuf);
  477. pBuf += 24;
  478. }
  479. }
  480. return(iRes);
  481. }
  482. int GetEWKBtoMultiPointLen(unsigned char *sBuf, int iDim, long *plen,
  483. unsigned char ucByteOrder)
  484. {
  485. int iRes = 0;
  486. unsigned long lcnt = GetLong(&sBuf, ucByteOrder, &iRes);
  487. unsigned char byteorder;
  488. long lsize = 0;
  489. unsigned long ulType;
  490. int ilocDim;
  491. int iType;
  492. if(lcnt > 1) // geometry collection
  493. {
  494. (*plen) += 20; // 16 bytes for geometry GUID and 4 bytes for collection count
  495. int i = 0;
  496. int ilen = 1;
  497. while((i < (int)lcnt) && (ilen > 0))
  498. {
  499. byteorder = GetByte(&sBuf, &iRes);
  500. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  501. ilocDim = ulType / 1000;
  502. iType = ulType - 1000*ilocDim;
  503. ilocDim += 2;
  504. lsize = 0;
  505. if(iType == 1)
  506. {
  507. ilen = GetEWKBtoPointLen(sBuf, iDim, &lsize, byteorder);
  508. sBuf += ilen;
  509. iRes += ilen;
  510. (*plen) += (4 + lsize); // 4 bytes for collection item size
  511. }
  512. else ilen = 0;
  513. i++;
  514. }
  515. }
  516. else if(lcnt == 1) // polyline geometry
  517. {
  518. byteorder = GetByte(&sBuf, &iRes);
  519. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  520. ilocDim = ulType / 1000;
  521. iType = ulType - 1000*ilocDim;
  522. ilocDim += 2;
  523. lsize = 0;
  524. if(iType == 1)
  525. {
  526. iRes += GetEWKBtoPointLen(sBuf, iDim, &lsize, byteorder);
  527. (*plen) += lsize;
  528. }
  529. }
  530. return(iRes);
  531. }
  532. int EWKBtoMultiPoint(unsigned char *sBuf, unsigned char *pBuf, int iDim,
  533. long *plen, unsigned char ucByteOrder)
  534. {
  535. int iRes = 0;
  536. unsigned long lcnt = GetLong(&sBuf, ucByteOrder, &iRes);
  537. unsigned char byteorder;
  538. long lsize = 0;
  539. unsigned long ulType;
  540. int ilocDim;
  541. int iType;
  542. if(lcnt > 1) // geometry collection
  543. {
  544. memcpy(pBuf, &GID_GeometryCollection, 16);
  545. pBuf += 16;
  546. *(unsigned long*)pBuf = lcnt;
  547. pBuf += 4;
  548. (*plen) += 20; // 16 vytes for geometry GUID amd 4 bytes for collection count
  549. int i = 0;
  550. int ilen = 1;
  551. while((i < (int)lcnt) && (ilen > 0))
  552. {
  553. byteorder = GetByte(&sBuf, &iRes);
  554. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  555. ilocDim = ulType / 1000;
  556. iType = ulType - 1000*ilocDim;
  557. ilocDim += 2;
  558. lsize = 0;
  559. if(iType == 1)
  560. {
  561. ilen = EWKBtoPoint(sBuf, &pBuf[4], iDim, &lsize, byteorder);
  562. *(unsigned long*)pBuf = lsize;
  563. sBuf += ilen;
  564. iRes += ilen;
  565. pBuf += (4 + lsize);
  566. (*plen) += (4 + lsize); // 4 bytes for collection item size
  567. }
  568. else ilen = 0;
  569. i++;
  570. }
  571. }
  572. else if(lcnt == 1) // point geometry
  573. {
  574. byteorder = GetByte(&sBuf, &iRes);
  575. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  576. ilocDim = ulType / 1000;
  577. iType = ulType - 1000*ilocDim;
  578. ilocDim += 2;
  579. if(iType == 1)
  580. {
  581. iRes += EWKBtoPoint(sBuf, pBuf, iDim, &lsize, byteorder);
  582. (*plen) += lsize;
  583. }
  584. }
  585. return(iRes);
  586. }
  587. int GetEWKBtoMultiLineStringLen(unsigned char *sBuf, int iDim, long *plen,
  588. unsigned char ucByteOrder)
  589. {
  590. int iRes = 0;
  591. unsigned long lcnt = GetLong(&sBuf, ucByteOrder, &iRes);
  592. unsigned char byteorder;
  593. long lsize = 0;
  594. unsigned long ulType;
  595. int ilocDim;
  596. int iType;
  597. if(lcnt > 1) // geometry collection
  598. {
  599. (*plen) += 20; // 16 bytes for geometry GUID and 4 bytes for collection count
  600. int i = 0;
  601. int ilen = 1;
  602. while((i < (int)lcnt) && (ilen > 0))
  603. {
  604. byteorder = GetByte(&sBuf, &iRes);
  605. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  606. ilocDim = ulType / 1000;
  607. iType = ulType - 1000*ilocDim;
  608. ilocDim += 2;
  609. lsize = 0;
  610. if(iType == 2)
  611. {
  612. ilen = GetEWKBtoLineStringLen(sBuf, iDim, &lsize, byteorder,
  613. true);
  614. sBuf += ilen;
  615. iRes += ilen;
  616. (*plen) += (4 + lsize); // 4 bytes for collection item size
  617. }
  618. else ilen = 0;
  619. i++;
  620. }
  621. }
  622. else if(lcnt == 1) // polyline geometry
  623. {
  624. byteorder = GetByte(&sBuf, &iRes);
  625. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  626. ilocDim = ulType / 1000;
  627. iType = ulType - 1000*ilocDim;
  628. ilocDim += 2;
  629. lsize = 0;
  630. if(iType == 2)
  631. {
  632. iRes += GetEWKBtoLineStringLen(sBuf, iDim, &lsize, byteorder,
  633. true);
  634. (*plen) += lsize;
  635. }
  636. }
  637. return(iRes);
  638. }
  639. int EWKBtoMultiLineString(unsigned char *sBuf, unsigned char *pBuf, int iDim,
  640. long *plen, unsigned char ucByteOrder)
  641. {
  642. int iRes = 0;
  643. unsigned long lcnt = GetLong(&sBuf, ucByteOrder, &iRes);
  644. unsigned char byteorder;
  645. long lsize = 0;
  646. unsigned long ulType;
  647. int ilocDim;
  648. int iType;
  649. if(lcnt > 1) // geometry collection
  650. {
  651. memcpy(pBuf, &GID_GeometryCollection, 16);
  652. pBuf += 16;
  653. *(unsigned long*)pBuf = lcnt;
  654. pBuf += 4;
  655. (*plen) += 20; // 16 vytes for geometry GUID amd 4 bytes for collection count
  656. int i = 0;
  657. int ilen = 1;
  658. while((i < (int)lcnt) && (ilen > 0))
  659. {
  660. byteorder = GetByte(&sBuf, &iRes);
  661. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  662. ilocDim = ulType / 1000;
  663. iType = ulType - 1000*ilocDim;
  664. ilocDim += 2;
  665. lsize = 0;
  666. if(iType == 2)
  667. {
  668. ilen = EWKBtoLineString(sBuf, &pBuf[4], iDim, &lsize, byteorder,
  669. NULL);
  670. *(unsigned long*)pBuf = lsize;
  671. sBuf += ilen;
  672. iRes += ilen;
  673. pBuf += (4 + lsize);
  674. (*plen) += (4 + lsize); // 4 bytes for collection item size
  675. }
  676. else ilen = 0;
  677. i++;
  678. }
  679. }
  680. else if(lcnt == 1) // polyline geometry
  681. {
  682. byteorder = GetByte(&sBuf, &iRes);
  683. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  684. ilocDim = ulType / 1000;
  685. iType = ulType - 1000*ilocDim;
  686. ilocDim += 2;
  687. if(iType == 2)
  688. {
  689. iRes += EWKBtoLineString(sBuf, pBuf, iDim, &lsize, byteorder,
  690. NULL);
  691. (*plen) += lsize;
  692. }
  693. }
  694. return(iRes);
  695. }
  696. int GetEWKBtoMultiPolygonLen(unsigned char *sBuf, int iDim, long *plen,
  697. unsigned char ucByteOrder)
  698. {
  699. int iRes = 0;
  700. unsigned long lcnt = GetLong(&sBuf, ucByteOrder, &iRes);
  701. unsigned char byteorder;
  702. long lsize = 0;
  703. unsigned long ulType;
  704. int ilocDim;
  705. int iType;
  706. if(lcnt > 1) // geometry collection
  707. {
  708. (*plen) += 20; // 16 bytes for geometry GUID and 4 bytes for collection count
  709. int i = 0;
  710. int ilen = 1;
  711. while((i < (int)lcnt) && (ilen > 0))
  712. {
  713. byteorder = GetByte(&sBuf, &iRes);
  714. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  715. ilocDim = ulType / 1000;
  716. iType = ulType - 1000*ilocDim;
  717. ilocDim += 2;
  718. lsize = 0;
  719. if(iType == 3)
  720. {
  721. ilen = GetEWKBtoPolygonLen(sBuf, iDim, &lsize, byteorder);
  722. sBuf += ilen;
  723. iRes += ilen;
  724. (*plen) += (4 + lsize); // 4 bytes for collection item size
  725. }
  726. else ilen = 0;
  727. i++;
  728. }
  729. }
  730. else if(lcnt == 1) // boundary or polygon geometry
  731. {
  732. byteorder = GetByte(&sBuf, &iRes);
  733. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  734. ilocDim = ulType / 1000;
  735. iType = ulType - 1000*ilocDim;
  736. ilocDim += 2;
  737. lsize = 0;
  738. if(iType == 3)
  739. {
  740. iRes += GetEWKBtoPolygonLen(sBuf, iDim, &lsize, byteorder);
  741. (*plen) += lsize;
  742. }
  743. }
  744. return(iRes);
  745. }
  746. int EWKBtoMultiPolygon(unsigned char *sBuf, unsigned char *pBuf, int iDim,
  747. long *plen, unsigned char ucByteOrder)
  748. {
  749. int iRes = 0;
  750. unsigned long lcnt = GetLong(&sBuf, ucByteOrder, &iRes);
  751. unsigned char byteorder;
  752. long lsize = 0;
  753. unsigned long ulType;
  754. int ilocDim;
  755. int iType;
  756. if(lcnt > 1) // geometry collection
  757. {
  758. memcpy(pBuf, &GID_GeometryCollection, 16);
  759. pBuf += 16;
  760. *(unsigned long*)pBuf = lcnt;
  761. pBuf += 4;
  762. (*plen) += 20; // 16 vytes for geometry GUID amd 4 bytes for collection count
  763. int i = 0;
  764. int ilen = 1;
  765. while((i < (int)lcnt) && (ilen > 0))
  766. {
  767. byteorder = GetByte(&sBuf, &iRes);
  768. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  769. ilocDim = ulType / 1000;
  770. iType = ulType - 1000*ilocDim;
  771. ilocDim += 2;
  772. lsize = 0;
  773. if(iType == 3)
  774. {
  775. ilen = EWKBtoPolygon(sBuf, &pBuf[4], iDim, &lsize, byteorder);
  776. *(unsigned long*)pBuf = lsize;
  777. sBuf += ilen;
  778. iRes += ilen;
  779. pBuf += (4 + lsize);
  780. (*plen) += (4 + lsize); // 4 bytes for collection item size
  781. }
  782. else ilen = 0;
  783. i++;
  784. }
  785. }
  786. else if(lcnt == 1) // boundary or polygon geometry
  787. {
  788. byteorder = GetByte(&sBuf, &iRes);
  789. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  790. ilocDim = ulType / 1000;
  791. iType = ulType - 1000*ilocDim;
  792. ilocDim += 2;
  793. if(iType == 3)
  794. {
  795. iRes += EWKBtoPolygon(sBuf, pBuf, iDim, &lsize, byteorder);
  796. (*plen) += lsize;
  797. }
  798. }
  799. return(iRes);
  800. }
  801. int GetEWKBtoCircularStringLen(unsigned char *sBuf, int iDim, long *plen,
  802. unsigned char ucByteOrder, bool bWriteGUID)
  803. {
  804. int iRes = 0;
  805. unsigned long lcnt = GetLong(&sBuf, ucByteOrder, &iRes);
  806. double xStart[3], xMiddle[3], xEnd[3];
  807. if(lcnt > 3) // composite polyline geometry
  808. {
  809. int k = lcnt/2;
  810. if(bWriteGUID)
  811. {
  812. (*plen) += 16; // 16 bytes for geometry GUID
  813. (*plen) += 4; // 4 bytes for count
  814. }
  815. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, xEnd);
  816. for(int i = 0; i < k; i++)
  817. {
  818. xStart[0] = xEnd[0];
  819. xStart[1] = xEnd[1];
  820. xStart[2] = xEnd[2];
  821. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, xMiddle);
  822. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, xEnd);
  823. (*plen) += (4 + GetArcGeomSize(xStart, xMiddle, xEnd));
  824. }
  825. }
  826. else if(lcnt == 3) // arc geometry or composite polyline, if it is a circle
  827. // or can be also line geometry
  828. {
  829. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, xStart);
  830. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, xMiddle);
  831. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, xEnd);
  832. if((fabs(xEnd[0] - xStart[0]) < gdPrecLim) &&
  833. (fabs(xEnd[1] - xStart[1]) < gdPrecLim))
  834. {
  835. if(bWriteGUID)
  836. {
  837. (*plen) += 16; // 16 bytes for geometry GUID
  838. (*plen) += 4; // 4 bytes for count
  839. }
  840. // the geometry is whole circle, so we must represent it as
  841. // composite polyline geometry with two arcs
  842. (*plen) += 200; // 2x4 bytes for item size and 2x96 for two arcs
  843. }
  844. else
  845. {
  846. // the geometry is a pure arc
  847. (*plen) += GetArcGeomSize(xStart, xMiddle, xEnd);
  848. }
  849. }
  850. return(iRes);
  851. }
  852. // if plItemCount is NULL, then we are not interested in it, which in turn
  853. // means that we want to write also the base GUID
  854. int EWKBtoCircularString(unsigned char *sBuf, unsigned char *pBuf, int iDim,
  855. long *plen, unsigned char ucByteOrder, unsigned long *plItemCount)
  856. {
  857. #if DBGLEVEL > 2
  858. WriteLogFile("EWKBtoCircularString\r\n", true);
  859. #endif // DBGLEVEL
  860. int iRes = 0;
  861. unsigned long lcnt = GetLong(&sBuf, ucByteOrder, &iRes);
  862. unsigned char *tmpBuf;
  863. double xStart[3], xMiddle[3], xEnd[3];
  864. if(lcnt > 3) // composite polyline geometry
  865. {
  866. int k = lcnt/2;
  867. if(plItemCount) (*plItemCount) += k;
  868. else
  869. {
  870. memcpy(pBuf, &GID_CompositePolylineGeometry, 16);
  871. pBuf += 16;
  872. (*plen) += 16; // 16 bytes for geometry GUID
  873. *(long*)pBuf = k;
  874. pBuf += 4;
  875. (*plen) += 4; // 4 bytes for count
  876. }
  877. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, xEnd);
  878. long llen;
  879. for(int i = 0; i < k; i++)
  880. {
  881. xStart[0] = xEnd[0];
  882. xStart[1] = xEnd[1];
  883. xStart[2] = xEnd[2];
  884. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, xMiddle);
  885. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, xEnd);
  886. tmpBuf = WriteArcGeometry(&pBuf[4], xStart, xMiddle, xEnd);
  887. llen = (tmpBuf - &pBuf[4]);
  888. *(long*)pBuf = llen;
  889. (*plen) += (4 + llen);
  890. pBuf = tmpBuf;
  891. }
  892. }
  893. else if(lcnt == 3) // arc geometry or composite polyline, if it is a circle
  894. // or can be also line geometry
  895. {
  896. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, xStart);
  897. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, xMiddle);
  898. GetTriple(&sBuf, ucByteOrder, iDim, &iRes, xEnd);
  899. if((fabs(xEnd[0] - xStart[0]) < gdPrecLim) &&
  900. (fabs(xEnd[1] - xStart[1]) < gdPrecLim))
  901. {
  902. // the geometry is whole circle, so we must represent it as
  903. // composite polyline geometry with two arcs
  904. if(plItemCount) (*plItemCount) += 2;
  905. else
  906. {
  907. memcpy(pBuf, &GID_CompositePolylineGeometry, 16);
  908. pBuf += 16;
  909. (*plen) += 16; // 16 bytes for geometry GUID
  910. *(unsigned long*)pBuf = 2;
  911. pBuf += 4;
  912. (*plen) += 4; // 4 bytes for count
  913. }
  914. (*plen) += 200; // 2x4 bytes for item size and 2x96 for two arcs
  915. *(unsigned long*)pBuf = 96;
  916. pBuf += 4;
  917. memcpy(pBuf, &GID_ArcGeometry, 16);
  918. pBuf += 16;
  919. *(double*)pBuf = xStart[0];
  920. pBuf += 8;
  921. *(double*)pBuf = xStart[1];
  922. pBuf += 8;
  923. *(double*)pBuf = xStart[2];
  924. pBuf += 8;
  925. *(double*)pBuf = xMiddle[0];
  926. pBuf += 8;
  927. *(double*)pBuf = xMiddle[1];
  928. pBuf += 8;
  929. *(double*)pBuf = xMiddle[2];
  930. pBuf += 8;
  931. double D = (xMiddle[0] - xStart[0])*(xMiddle[0] - xStart[0]) +
  932. (xMiddle[1] - xStart[1])*(xMiddle[1] - xStart[1]);
  933. double dnorm[3];
  934. double r = D;
  935. if(D > gdPrecLim)
  936. {
  937. r = sqrt(D);
  938. double vtmp[3];
  939. vtmp[0] = (xMiddle[0] - xStart[0])/r;
  940. vtmp[1] = (xStart[1] - xMiddle[1])/r;
  941. vtmp[2] = 0.0;
  942. dnorm[0] = vtmp[1]*(xMiddle[2] - xStart[2]);
  943. // - vtmp[2]*(xMiddle[1] - xStart[1]) = 0
  944. dnorm[1] = // vtmp[2]*(xMiddle[0] - xStart[0]) = 0
  945. -vtmp[0]*(xMiddle[2] - xStart[2]);
  946. dnorm[2] = vtmp[0]*(xMiddle[1] - xStart[1]) -
  947. vtmp[1]*(xMiddle[0] - xStart[0]);
  948. D = dnorm[0]*dnorm[0] + dnorm[1]*dnorm[1] + dnorm[2]*dnorm[2];
  949. D = sqrt(D);
  950. dnorm[0] /= D;
  951. dnorm[1] /= D;
  952. dnorm[2] /= D;
  953. }
  954. else
  955. {
  956. dnorm[0] = 0.0;
  957. dnorm[1] = 0.0;
  958. dnorm[2] = 1.0;
  959. }
  960. r /= 2.0;
  961. *(double*)pBuf = dnorm[0];
  962. pBuf += 8;
  963. *(double*)pBuf = dnorm[1];
  964. pBuf += 8;
  965. *(double*)pBuf = dnorm[2];
  966. pBuf += 8;
  967. *(double*)pBuf = r;
  968. pBuf += 8;
  969. *(unsigned long*)pBuf = 96;
  970. pBuf += 4;
  971. memcpy(pBuf, &GID_ArcGeometry, 16);
  972. pBuf += 16;
  973. *(double*)pBuf = xMiddle[0];
  974. pBuf += 8;
  975. *(double*)pBuf = xMiddle[1];
  976. pBuf += 8;
  977. *(double*)pBuf = xMiddle[2];
  978. pBuf += 8;
  979. *(double*)pBuf = xStart[0];
  980. pBuf += 8;
  981. *(double*)pBuf = xStart[1];
  982. pBuf += 8;
  983. *(double*)pBuf = xStart[2];
  984. pBuf += 8;
  985. *(double*)pBuf = dnorm[0];
  986. pBuf += 8;
  987. *(double*)pBuf = dnorm[1];
  988. pBuf += 8;
  989. *(double*)pBuf = dnorm[2];
  990. pBuf += 8;
  991. *(double*)pBuf = r;
  992. pBuf += 8;
  993. }
  994. else
  995. {
  996. if(plItemCount) (*plItemCount) += 1;
  997. tmpBuf = WriteArcGeometry(pBuf, xStart, xMiddle, xEnd);
  998. (*plen) += (tmpBuf - pBuf);
  999. pBuf = tmpBuf;
  1000. }
  1001. }
  1002. return(iRes);
  1003. }
  1004. int GetEWKBtoCompoundCurveLen(unsigned char *sBuf, int iDim, long *plen,
  1005. unsigned char ucByteOrder, bool bWriteGUID)
  1006. {
  1007. int iRes = 0;
  1008. unsigned long lcnt = GetLong(&sBuf, ucByteOrder, &iRes);
  1009. unsigned char byteorder;
  1010. long lsize = 0;
  1011. unsigned long ulType;
  1012. int ilocDim;
  1013. int iType;
  1014. if(lcnt > 1) // composite polyline
  1015. {
  1016. if(bWriteGUID)
  1017. (*plen) += 20; // 16 bytes for geometry GUID and 4 bytes for collection count
  1018. int i = 0;
  1019. int ilen = 1;
  1020. while((i < (int)lcnt) && (ilen > 0))
  1021. {
  1022. byteorder = GetByte(&sBuf, &iRes);
  1023. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  1024. ilocDim = ulType / 1000;
  1025. iType = ulType - 1000*ilocDim;
  1026. ilocDim += 2;
  1027. lsize = 0;
  1028. switch(iType)
  1029. {
  1030. case 2:
  1031. ilen = GetEWKBtoLineStringLen(sBuf, iDim, &lsize, byteorder,
  1032. true);
  1033. sBuf += ilen;
  1034. iRes += ilen;
  1035. (*plen) += (4 + lsize); // 4 bytes for collection item size
  1036. break;
  1037. case 8:
  1038. ilen = GetEWKBtoCircularStringLen(sBuf, iDim, &lsize, byteorder,
  1039. false);
  1040. sBuf += ilen;
  1041. iRes += ilen;
  1042. (*plen) += (4 + lsize);
  1043. break;
  1044. default:
  1045. ilen = 0;
  1046. }
  1047. i++;
  1048. }
  1049. }
  1050. else if(lcnt == 1) // polyline geometry
  1051. {
  1052. byteorder = GetByte(&sBuf, &iRes);
  1053. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  1054. ilocDim = ulType / 1000;
  1055. iType = ulType - 1000*ilocDim;
  1056. ilocDim += 2;
  1057. lsize = 0;
  1058. switch(iType)
  1059. {
  1060. case 2:
  1061. iRes += GetEWKBtoLineStringLen(sBuf, iDim, &lsize, byteorder, true);
  1062. break;
  1063. case 8:
  1064. iRes += GetEWKBtoCircularStringLen(sBuf, iDim, &lsize, byteorder,
  1065. bWriteGUID);
  1066. break;
  1067. }
  1068. (*plen) += lsize;
  1069. }
  1070. return(iRes);
  1071. }
  1072. // if plItemCount is NULL, then we are not interested in it, which in turn
  1073. // means that we want to write also the base GUID
  1074. int EWKBtoCompoundCurve(unsigned char *sBuf, unsigned char *pBuf, int iDim,
  1075. long *plen, unsigned char ucByteOrder, unsigned long *plItemCount)
  1076. {
  1077. #if DBGLEVEL > 2
  1078. WriteLogFile("EWKBtoCompoundCurve\r\n", true);
  1079. #endif // DBGLEVEL
  1080. int iRes = 0;
  1081. unsigned long lcnt = GetLong(&sBuf, ucByteOrder, &iRes);
  1082. unsigned char byteorder;
  1083. long lsize = 0;
  1084. unsigned long ulType, ltruecount;
  1085. int ilocDim;
  1086. int iType;
  1087. unsigned char *pSaveBuf = NULL;
  1088. if(lcnt > 1) // composite polyline
  1089. {
  1090. if(!plItemCount)
  1091. {
  1092. memcpy(pBuf, &GID_CompositePolylineGeometry, 16);
  1093. pBuf += 16;
  1094. pSaveBuf = pBuf;
  1095. ltruecount = 0;
  1096. //*(unsigned long*)pBuf = lcnt;
  1097. pBuf += 4;
  1098. (*plen) += 20; // 16 bytes for geometry GUID amd 4 bytes for collection count
  1099. }
  1100. int i = 0;
  1101. int ilen = 1;
  1102. while((i < (int)lcnt) && (ilen > 0))
  1103. {
  1104. byteorder = GetByte(&sBuf, &iRes);
  1105. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  1106. ilocDim = ulType / 1000;
  1107. iType = ulType - 1000*ilocDim;
  1108. ilocDim += 2;
  1109. lsize = 0;
  1110. switch(iType)
  1111. {
  1112. case 2:
  1113. ilen = EWKBtoLineString(sBuf, &pBuf[4], iDim, &lsize, byteorder,
  1114. NULL);
  1115. *(unsigned long*)pBuf = lsize;
  1116. sBuf += ilen;
  1117. iRes += ilen;
  1118. pBuf += (4 + lsize);
  1119. (*plen) += (4 + lsize); // 4 bytes for collection item size
  1120. ltruecount += 1;
  1121. break;
  1122. case 8:
  1123. ilen = EWKBtoCircularString(sBuf, &pBuf[4], iDim, &lsize,
  1124. byteorder, &ltruecount);
  1125. *(unsigned long*)pBuf = lsize;
  1126. sBuf += ilen;
  1127. iRes += ilen;
  1128. pBuf += (4 + lsize);
  1129. (*plen) += (4 + lsize);
  1130. break;
  1131. default:
  1132. ilen = 0;
  1133. }
  1134. i++;
  1135. }
  1136. if(plItemCount) (*plItemCount) += ltruecount;
  1137. else *(unsigned long*)pSaveBuf = ltruecount;
  1138. }
  1139. else if(lcnt == 1) // polyline geometry or arc
  1140. {
  1141. byteorder = GetByte(&sBuf, &iRes);
  1142. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  1143. ilocDim = ulType / 1000;
  1144. iType = ulType - 1000*ilocDim;
  1145. ilocDim += 2;
  1146. lsize = 0;
  1147. switch(iType)
  1148. {
  1149. case 2:
  1150. iRes += EWKBtoLineString(sBuf, pBuf, iDim, &lsize, byteorder,
  1151. NULL);
  1152. if(plItemCount) (*plItemCount) += 1;
  1153. break;
  1154. case 8:
  1155. iRes += EWKBtoCircularString(sBuf, pBuf, iDim, &lsize, byteorder,
  1156. plItemCount);
  1157. break;
  1158. }
  1159. (*plen) += lsize;
  1160. }
  1161. return(iRes);
  1162. }
  1163. int GetEWKBtoCurvePolygonLen(unsigned char *sBuf, int iDim, long *plen,
  1164. unsigned char ucByteOrder)
  1165. {
  1166. int iRes = 0;
  1167. unsigned long ulLen = GetLong(&sBuf, ucByteOrder, &iRes);
  1168. unsigned char byteorder;
  1169. long lsize = 0;
  1170. unsigned long ulType;
  1171. int ilocDim;
  1172. int iType;
  1173. if(ulLen > 1) // boundary geometry
  1174. {
  1175. (*plen) += 20; // 16 bytes for geometry GUID and 4 bytes for boundary
  1176. // size, 4 bytes for holes size are covered in the while loop
  1177. // 16 bytes for collection GUID, 4 bytes for collection count
  1178. (*plen) += 20;
  1179. int i = 0;
  1180. int ilen = 1;
  1181. while((i < (int)ulLen) && (ilen > 0))
  1182. {
  1183. (*plen) += 4; // 4 bytes for collection item size
  1184. byteorder = GetByte(&sBuf, &iRes);
  1185. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  1186. ilocDim = ulType / 1000;
  1187. iType = ulType - 1000*ilocDim;
  1188. ilocDim += 2;
  1189. lsize = 0;
  1190. switch(iType)
  1191. {
  1192. case 2:
  1193. ilen = GetEWKBtoLineStringLen(sBuf, iDim, &lsize, byteorder,
  1194. false);
  1195. break;
  1196. case 8:
  1197. ilen = GetEWKBtoCircularStringLen(sBuf, iDim, &lsize, byteorder,
  1198. false);
  1199. break;
  1200. case 9:
  1201. ilen = GetEWKBtoCompoundCurveLen(sBuf, iDim, &lsize, byteorder,
  1202. false);
  1203. break;
  1204. default:
  1205. ilen = 0;
  1206. }
  1207. sBuf += ilen;
  1208. iRes += ilen;
  1209. (*plen) += (20 + lsize); // 4 bytes for collection item count
  1210. i++;
  1211. }
  1212. }
  1213. else if(ulLen == 1) // composite polygon geometry or polygon geometry
  1214. {
  1215. byteorder = GetByte(&sBuf, &iRes);
  1216. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  1217. ilocDim = ulType / 1000;
  1218. iType = ulType - 1000*ilocDim;
  1219. ilocDim += 2;
  1220. switch(iType)
  1221. {
  1222. case 2:
  1223. (*plen) += 20; // 16 bytes for Geom GUID, 4 bytes for count
  1224. iRes += GetEWKBtoLineStringLen(sBuf, iDim, plen, byteorder, false);
  1225. break;
  1226. case 8:
  1227. (*plen) += 20; // 16 bytes for Geom GUID, 4 bytes for count
  1228. iRes += GetEWKBtoCircularStringLen(sBuf, iDim, plen, byteorder,
  1229. false);
  1230. break;
  1231. case 9:
  1232. (*plen) += 20; // 16 bytes for Geom GUID, 4 bytes for count
  1233. iRes += GetEWKBtoCompoundCurveLen(sBuf, iDim, plen, byteorder,
  1234. false);
  1235. break;
  1236. }
  1237. }
  1238. return(iRes);
  1239. }
  1240. int EWKBtoCurvePolygon(unsigned char *sBuf, unsigned char *pBuf, int iDim,
  1241. long *plen, unsigned char ucByteOrder)
  1242. {
  1243. #if DBGLEVEL > 2
  1244. WriteLogFile("EWKBtoCurvePolygon\r\n", true);
  1245. #endif // DBGLEVEL
  1246. int iRes = 0;
  1247. unsigned long ulLen = GetLong(&sBuf, ucByteOrder, &iRes);
  1248. unsigned char byteorder;
  1249. long lsize = 0;
  1250. unsigned long ulType;
  1251. int ilocDim;
  1252. int iType;
  1253. unsigned char *pSaveBuf = NULL, *pSaveBuf2 = NULL;
  1254. unsigned long ltruecount = 0;
  1255. if(ulLen > 1) // boundary geometry
  1256. {
  1257. memcpy(pBuf, &GID_BoundaryGeometry, 16);
  1258. pBuf += 16;
  1259. (*plen) += 16; // 16 bytes for Geom GUID
  1260. pSaveBuf = pBuf;
  1261. pBuf += 4;
  1262. (*plen) += 4; // 4 bytes for boundary size
  1263. byteorder = GetByte(&sBuf, &iRes);
  1264. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  1265. ilocDim = ulType / 1000;
  1266. iType = ulType - 1000*ilocDim;
  1267. ilocDim += 2;
  1268. lsize = 0;
  1269. int ilen = 1;
  1270. ltruecount = 0;
  1271. switch(iType)
  1272. {
  1273. case 2:
  1274. memcpy(pBuf, &GID_PolygonGeometry, 16);
  1275. pBuf += 16;
  1276. pSaveBuf2 = pBuf;
  1277. pBuf += 4;
  1278. (*plen) += 20; // 16 bytes for Geom GUID, 4 bytes for count
  1279. ilen = EWKBtoLineString(sBuf, pBuf, iDim, &lsize, byteorder,
  1280. &ltruecount);
  1281. *(unsigned long*)pSaveBuf2 = ltruecount;
  1282. break;
  1283. case 8:
  1284. memcpy(pBuf, &GID_CompositePolygonGeometry, 16);
  1285. pBuf += 16;
  1286. pSaveBuf2 = pBuf;
  1287. pBuf += 4;
  1288. (*plen) += 20; // 16 bytes for Geom GUID, 4 bytes for item count
  1289. ilen = EWKBtoCircularString(sBuf, pBuf, iDim, &lsize, byteorder,
  1290. &ltruecount);
  1291. *(unsigned long*)pSaveBuf2 = ltruecount;
  1292. break;
  1293. case 9:
  1294. memcpy(pBuf, &GID_CompositePolygonGeometry, 16);
  1295. pBuf += 16;
  1296. pSaveBuf2 = pBuf;
  1297. pBuf += 4;
  1298. (*plen) += 20; // 16 bytes for Geom GUID, 4 bytes for item count
  1299. ilen = EWKBtoCompoundCurve(sBuf, pBuf, iDim, &lsize, byteorder,
  1300. &ltruecount);
  1301. *(unsigned long*)pSaveBuf2 = ltruecount;
  1302. break;
  1303. default:
  1304. ilen = 0;
  1305. }
  1306. *(unsigned long*)pSaveBuf = (20 + lsize);
  1307. sBuf += ilen;
  1308. iRes += ilen;
  1309. pBuf += lsize;
  1310. (*plen) += lsize;
  1311. pSaveBuf = pBuf;
  1312. pBuf += 4;
  1313. (*plen) += 4;
  1314. memcpy(pBuf, &GID_GeometryCollection, 16);
  1315. pBuf += 16;
  1316. *(unsigned long*)pBuf = ulLen - 1;
  1317. pBuf += 4;
  1318. (*plen) += 20; // 16 bytes for Geom GUID, 4 bytes for item count
  1319. int ltotsize = 20;
  1320. int i = 1;
  1321. while((i < (int)ulLen) && (ilen > 0))
  1322. {
  1323. pSaveBuf2 = pBuf;
  1324. pBuf += 4;
  1325. (*plen) += 4;
  1326. byteorder = GetByte(&sBuf, &iRes);
  1327. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  1328. ilocDim = ulType / 1000;
  1329. iType = ulType - 1000*ilocDim;
  1330. ilocDim += 2;
  1331. lsize = 0;
  1332. ltruecount = 0;
  1333. switch(iType)
  1334. {
  1335. case 2:
  1336. memcpy(pBuf, &GID_PolygonGeometry, 16);
  1337. pBuf += 16;
  1338. (*plen) += 20; // 16 bytes for Geom GUID, 4 bytes for count
  1339. ilen = EWKBtoLineString(sBuf, &pBuf[4], iDim, &lsize, byteorder,
  1340. &ltruecount);
  1341. *(unsigned long*)pBuf = ltruecount;
  1342. break;
  1343. case 8:
  1344. memcpy(pBuf, &GID_CompositePolygonGeometry, 16);
  1345. pBuf += 16;
  1346. (*plen) += 20; // 16 bytes for Geom GUID, 4 bytes for item count
  1347. ilen = EWKBtoCircularString(sBuf, &pBuf[4], iDim, &lsize,
  1348. byteorder, &ltruecount);
  1349. *(unsigned long*)pBuf = ltruecount;
  1350. break;
  1351. case 9:
  1352. memcpy(pBuf, &GID_CompositePolygonGeometry, 16);
  1353. pBuf += 16;
  1354. (*plen) += 20; // 16 bytes for Geom GUID, 4 bytes for item count
  1355. ilen = EWKBtoCompoundCurve(sBuf, pBuf, iDim, &lsize, byteorder,
  1356. &ltruecount);
  1357. *(unsigned long*)pBuf = ltruecount;
  1358. break;
  1359. default:
  1360. ilen = 0;
  1361. }
  1362. *(unsigned long*)pSaveBuf2 = (20 + lsize);
  1363. sBuf += ilen;
  1364. iRes += ilen;
  1365. pBuf += (4 + lsize);
  1366. (*plen) += lsize;
  1367. ltotsize += (24 + lsize);
  1368. i++;
  1369. }
  1370. *(unsigned long*)pSaveBuf = ltotsize;
  1371. }
  1372. else if(ulLen == 1) // composite polygon geometry or polygon geometry
  1373. {
  1374. byteorder = GetByte(&sBuf, &iRes);
  1375. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  1376. ilocDim = ulType / 1000;
  1377. iType = ulType - 1000*ilocDim;
  1378. ilocDim += 2;
  1379. switch(iType)
  1380. {
  1381. case 2:
  1382. memcpy(pBuf, &GID_PolygonGeometry, 16);
  1383. pBuf += 16;
  1384. pSaveBuf = pBuf;
  1385. pBuf += 4;
  1386. (*plen) += 20; // 16 bytes for Geom GUID, 4 bytes for point count
  1387. ltruecount = 0;
  1388. iRes += EWKBtoLineString(sBuf, pBuf, iDim, plen, byteorder,
  1389. &ltruecount);
  1390. *(unsigned long*)pSaveBuf = ltruecount;
  1391. break;
  1392. case 8:
  1393. memcpy(pBuf, &GID_CompositePolygonGeometry, 16);
  1394. pBuf += 16;
  1395. pSaveBuf = pBuf;
  1396. pBuf += 4;
  1397. (*plen) += 20; // 16 bytes for Geom GUID, 4 bytes for item count
  1398. ltruecount = 0;
  1399. iRes += EWKBtoCircularString(sBuf, pBuf, iDim, plen, byteorder,
  1400. &ltruecount);
  1401. *(unsigned long*)pSaveBuf = ltruecount;
  1402. break;
  1403. case 9:
  1404. memcpy(pBuf, &GID_CompositePolygonGeometry, 16);
  1405. pBuf += 16;
  1406. pSaveBuf = pBuf;
  1407. pBuf += 4;
  1408. (*plen) += 20; // 16 bytes for Geom GUID, 4 bytes for item count
  1409. ltruecount = 0;
  1410. iRes += EWKBtoCompoundCurve(sBuf, pBuf, iDim, plen, byteorder,
  1411. &ltruecount);
  1412. *(unsigned long*)pSaveBuf = ltruecount;
  1413. break;
  1414. }
  1415. }
  1416. return(iRes);
  1417. }
  1418. int GetEWKBtoMultiCurveLen(unsigned char *sBuf, int iDim, long *plen,
  1419. unsigned char ucByteOrder)
  1420. {
  1421. int iRes = 0;
  1422. unsigned long ulLen = GetLong(&sBuf, ucByteOrder, &iRes);
  1423. unsigned char byteorder;
  1424. long lsize = 0;
  1425. unsigned long ulType;
  1426. int ilocDim;
  1427. int iType;
  1428. if(ulLen > 1) // geometry collection
  1429. {
  1430. // 16 bytes for collection GUID, 4 bytes for collection count
  1431. (*plen) += 20;
  1432. int i = 0;
  1433. int ilen = 1;
  1434. while((i < (int)ulLen) && (ilen > 0))
  1435. {
  1436. byteorder = GetByte(&sBuf, &iRes);
  1437. ulType = GetGeomType(&sBuf, byteorder, &iRes);
  1438. ilocDim = ulType / 1000;
  1439. iTyp

Large files files are truncated, but you can click here to view the full file