Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the geopoly_regular(X,Y,R,N) function to the geopoly extension. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
4505bbae58357eacab262b642b2a56d6 |
User & Date: | drh 2018-09-28 14:01:17.539 |
Context
2018-09-28
| ||
18:51 | Fix a bug in the sqlite_memstat virtual table that was causing it to report the amount of memory used as zero bytes. (check-in: 8a758a8721 user: drh tags: trunk) | |
14:01 | Add the geopoly_regular(X,Y,R,N) function to the geopoly extension. (check-in: 4505bbae58 user: drh tags: trunk) | |
13:18 | Make most geopoly functions pure. (check-in: 944e167a98 user: drh tags: trunk) | |
Changes
Changes to ext/rtree/geopoly.c.
︙ | ︙ | |||
481 482 483 484 485 486 487 488 489 490 491 492 493 494 | rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */ * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */ * 0.5; sqlite3_result_double(context, rArea); sqlite3_free(p); } } /* ** If pPoly is a polygon, compute its bounding box. Then: ** ** (1) if aCoord!=0 store the bounding box in aCoord, returning NULL ** (2) otherwise, compute a GeoPoly for the bounding box and return the ** new GeoPoly | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 | rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */ * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */ * 0.5; sqlite3_result_double(context, rArea); sqlite3_free(p); } } #define GEOPOLY_PI 3.1415926535897932385 /* Fast approximation for cosine(X) for X between -0.5*pi and 2*pi */ static double geopolyCosine(double r){ assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI ); if( r>=1.5*GEOPOLY_PI ){ r -= 2.0*GEOPOLY_PI; } if( r>=0.5*GEOPOLY_PI ){ return -geopolyCosine(r-GEOPOLY_PI); }else{ double r2 = r*r; double r3 = r2*r; double r5 = r3*r2; return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5; } } /* ** Function: geopoly_regular(X,Y,R,N) ** ** Construct a simple, convex, regular polygon centered at X, Y ** with circumradius R and with N sides. */ static void geopolyRegularFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ double x = sqlite3_value_double(argv[0]); double y = sqlite3_value_double(argv[1]); double r = sqlite3_value_double(argv[2]); int n = sqlite3_value_int(argv[3]); int i; GeoPoly *p; if( n<3 || r<=0.0 ) return; if( n>1000 ) n = 1000; p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) ); if( p==0 ){ sqlite3_result_error_nomem(context); return; } i = 1; p->hdr[0] = *(unsigned char*)&i; p->hdr[1] = 0; p->hdr[2] = (n>>8)&0xff; p->hdr[3] = n&0xff; for(i=0; i<n; i++){ double rAngle = 2.0*GEOPOLY_PI*i/n; p->a[i*2] = x - r*geopolyCosine(rAngle-0.5*GEOPOLY_PI); p->a[i*2+1] = y + r*geopolyCosine(rAngle); } sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT); sqlite3_free(p); } /* ** If pPoly is a polygon, compute its bounding box. Then: ** ** (1) if aCoord!=0 store the bounding box in aCoord, returning NULL ** (2) otherwise, compute a GeoPoly for the bounding box and return the ** new GeoPoly |
︙ | ︙ | |||
1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 | { geopolySvgFunc, -1, 1, "geopoly_svg" }, { geopolyWithinFunc, 2, 1, "geopoly_within" }, { geopolyContainsPointFunc, 3, 1, "geopoly_contains_point" }, { geopolyOverlapFunc, 2, 1, "geopoly_overlap" }, { geopolyDebugFunc, 1, 0, "geopoly_debug" }, { geopolyBBoxFunc, 1, 1, "geopoly_bbox" }, { geopolyXformFunc, 7, 1, "geopoly_xform" }, }; static const struct { void (*xStep)(sqlite3_context*,int,sqlite3_value**); void (*xFinal)(sqlite3_context*); const char *zName; } aAgg[] = { { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" }, | > | 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 | { geopolySvgFunc, -1, 1, "geopoly_svg" }, { geopolyWithinFunc, 2, 1, "geopoly_within" }, { geopolyContainsPointFunc, 3, 1, "geopoly_contains_point" }, { geopolyOverlapFunc, 2, 1, "geopoly_overlap" }, { geopolyDebugFunc, 1, 0, "geopoly_debug" }, { geopolyBBoxFunc, 1, 1, "geopoly_bbox" }, { geopolyXformFunc, 7, 1, "geopoly_xform" }, { geopolyRegularFunc, 4, 1, "geopoly_regular" }, }; static const struct { void (*xStep)(sqlite3_context*,int,sqlite3_value**); void (*xFinal)(sqlite3_context*); const char *zName; } aAgg[] = { { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" }, |
︙ | ︙ |
Changes to ext/rtree/visual01.txt.
︙ | ︙ | |||
581 582 583 584 585 586 587 588 589 | ) FROM geo1 WHERE geopoly_overlap(_shape,(SELECT poly FROM querypoly)); SELECT geopoly_svg(poly,'style="fill:none;stroke:black;stroke-width:2"') FROM querypoly; ROLLBACK; .print '</svg>' .print '</html>' | > > > > > > > > > > > > > | 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 | ) FROM geo1 WHERE geopoly_overlap(_shape,(SELECT poly FROM querypoly)); SELECT geopoly_svg(poly,'style="fill:none;stroke:black;stroke-width:2"') FROM querypoly; ROLLBACK; .print '</svg>' .print '<h1>Regular Polygons</h1>' .print '<svg width="1000" height="200" style="border:1px solid black">' SELECT geopoly_svg(geopoly_regular(100,100,40,3),'style="fill:none;stroke:red;stroke-width:1"'); SELECT geopoly_svg(geopoly_regular(200,100,40,4),'style="fill:none;stroke:orange;stroke-width:1"'); SELECT geopoly_svg(geopoly_regular(300,100,40,5),'style="fill:none;stroke:green;stroke-width:1"'); SELECT geopoly_svg(geopoly_regular(400,100,40,6),'style="fill:none;stroke:blue;stroke-width:1"'); SELECT geopoly_svg(geopoly_regular(500,100,40,7),'style="fill:none;stroke:purple;stroke-width:1"'); SELECT geopoly_svg(geopoly_regular(600,100,40,8),'style="fill:none;stroke:red;stroke-width:1"'); SELECT geopoly_svg(geopoly_regular(700,100,40,10),'style="fill:none;stroke:orange;stroke-width:1"'); SELECT geopoly_svg(geopoly_regular(800,100,40,20),'style="fill:none;stroke:green;stroke-width:1"'); SELECT geopoly_svg(geopoly_regular(900,100,40,30),'style="fill:none;stroke:blue;stroke-width:1"'); .print '</svg>' .print '</html>' |