11// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
22// @ts -ignore
3- import reproject from 'reproject' ;
43import PolyToLine from '@turf/polygon-to-line' ;
54import booleanClockwise from '@turf/boolean-clockwise' ;
65import simplify from 'simplify-js' ;
@@ -532,16 +531,31 @@ export class FeatureTiles {
532531 }
533532
534533 /**
535- * Transform geojson to web mercator if it is in another projection.
536- * @param geoJson
537- * @param tileProjection
538- */
539- transformGeometry ( geoJson : any , tileProjection : string ) : any {
540- const targetProjection = Projection . getConverter ( tileProjection ) ;
541- if ( this . projection !== targetProjection ) {
542- return reproject . reproject ( geoJson , this . projection , targetProjection ) ;
534+ * Handles the generation of a function for transforming coordinates from the source projection into the target tile's
535+ * projection. These coordinates are then converted into pixel coordinates.
536+ * @param targetProjection
537+ */
538+ getTransformFunction ( targetProjection ) : Function {
539+ const projection = Projection . getConverter ( targetProjection ) ;
540+ if ( Projection . convertersMatch ( projection , this . projection ) ) {
541+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
542+ return coordinate => coordinate ;
543+ } else if ( Projection . isWebMercator ( projection ) && Projection . isWGS84 ( this . projection ) ) {
544+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
545+ return coordinate => {
546+ return Projection . getConverterFromConverters ( this . projection , targetProjection ) . forward ( [
547+ Math . max (
548+ ProjectionConstants . WEB_MERCATOR_MIN_LON_RANGE ,
549+ Math . min ( ProjectionConstants . WEB_MERCATOR_MAX_LON_RANGE , coordinate [ 0 ] ) ,
550+ ) ,
551+ Math . max (
552+ ProjectionConstants . WEB_MERCATOR_MIN_LAT_RANGE ,
553+ Math . min ( ProjectionConstants . WEB_MERCATOR_MAX_LAT_RANGE , coordinate [ 1 ] ) ,
554+ ) ,
555+ ] ) ;
556+ } ;
543557 } else {
544- return geoJson ;
558+ return Projection . getConverterFromConverters ( this . projection , targetProjection ) . forward ;
545559 }
546560 }
547561
@@ -574,6 +588,7 @@ export class FeatureTiles {
574588 const featureCount = this . featureDao . countInBoundingBox ( expandedBoundingBox , tileProjection ) ;
575589 if ( featureCount > 0 ) {
576590 if ( this . maxFeaturesPerTile == null || featureCount <= this . maxFeaturesPerTile ) {
591+ const transform = this . getTransformFunction ( tileProjection ) ;
577592 const iterator = this . featureDao . fastQueryBoundingBox ( expandedBoundingBox , tileProjection ) ;
578593 for ( const featureRow of iterator ) {
579594 if ( featureRow . geometry != null ) {
@@ -587,7 +602,7 @@ export class FeatureTiles {
587602 }
588603 const style = this . getFeatureStyle ( featureRow ) ;
589604 try {
590- await this . drawGeometry ( this . transformGeometry ( geojson , tileProjection ) , context , boundingBox , style ) ;
605+ await this . drawGeometry ( geojson , context , boundingBox , style , transform ) ;
591606 } catch ( e ) {
592607 console . error (
593608 'Failed to draw feature in tile. Id: ' + featureRow . id + ', Table: ' + this . featureDao . table_name ,
@@ -633,6 +648,7 @@ export class FeatureTiles {
633648 featureDao . table . getIdColumn ( ) . getName ( ) ,
634649 featureDao . table . getGeometryColumn ( ) . getName ( ) ,
635650 ] ) ;
651+ const transform = this . getTransformFunction ( tileProjection ) ;
636652 for ( const row of each ) {
637653 const fr = featureDao . getRow ( row ) ;
638654 if ( fr . geometry != null ) {
@@ -647,7 +663,7 @@ export class FeatureTiles {
647663 if ( gj != null ) {
648664 const style = this . getFeatureStyle ( fr ) ;
649665 try {
650- await this . drawGeometry ( this . transformGeometry ( gj , tileProjection ) , context , boundingBox , style ) ;
666+ await this . drawGeometry ( gj , context , boundingBox , style , transform ) ;
651667 } catch ( e ) {
652668 console . error ( 'Failed to draw feature in tile. Id: ' + fr . id + ', Table: ' + this . featureDao . table_name ) ;
653669 }
@@ -666,14 +682,22 @@ export class FeatureTiles {
666682 * @param context
667683 * @param boundingBox
668684 * @param featureStyle
685+ * @param transform
669686 */
670- async drawPoint ( geoJson : any , context : any , boundingBox : BoundingBox , featureStyle : FeatureStyle ) : Promise < void > {
687+ async drawPoint (
688+ geoJson : any ,
689+ context : any ,
690+ boundingBox : BoundingBox ,
691+ featureStyle : FeatureStyle ,
692+ transform : Function ,
693+ ) : Promise < void > {
671694 let width : number ;
672695 let height : number ;
673696 let iconX : number ;
674697 let iconY : number ;
675- const x = TileBoundingBoxUtils . getXPixel ( this . tileWidth , boundingBox , geoJson . coordinates [ 0 ] ) ;
676- const y = TileBoundingBoxUtils . getYPixel ( this . tileHeight , boundingBox , geoJson . coordinates [ 1 ] ) ;
698+ const coordinate = transform ( geoJson . coordinates ) ;
699+ const x = TileBoundingBoxUtils . getXPixel ( this . tileWidth , boundingBox , coordinate [ 0 ] ) ;
700+ const y = TileBoundingBoxUtils . getYPixel ( this . tileHeight , boundingBox , coordinate [ 1 ] ) ;
677701 if ( featureStyle != null && featureStyle . useIcon ( ) ) {
678702 const iconRow = featureStyle . icon ;
679703 const image = await this . iconCache . createIcon ( iconRow ) ;
@@ -757,14 +781,18 @@ export class FeatureTiles {
757781 * @param context
758782 * @param boundingBox
759783 * @param isPolygon if this was a polygon
760- */
761- getPath ( lineString : any , context : any , boundingBox : BoundingBox , isPolygon = false ) : void {
762- lineString . coordinates = lineString . coordinates . map ( coordinate => [
763- TileBoundingBoxUtils . getXPixel ( this . tileWidth , boundingBox , coordinate [ 0 ] ) ,
764- TileBoundingBoxUtils . getYPixel ( this . tileHeight , boundingBox , coordinate [ 1 ] ) ,
765- ] ) ;
784+ * @param transform
785+ */
786+ getPath ( lineString : any , context : any , boundingBox : BoundingBox , isPolygon = false , transform : Function ) : void {
787+ lineString . coordinates = lineString . coordinates . map ( coordinate => {
788+ const transformedCoordinate = transform ( coordinate ) ;
789+ return [
790+ TileBoundingBoxUtils . getXPixel ( this . tileWidth , boundingBox , transformedCoordinate [ 0 ] ) ,
791+ TileBoundingBoxUtils . getYPixel ( this . tileHeight , boundingBox , transformedCoordinate [ 1 ] ) ,
792+ ] ;
793+ } ) ;
766794 const simplifiedLineString = this . simplifyGeometries ? this . simplifyPoints ( lineString , isPolygon ) : lineString ;
767- if ( simplifiedLineString != null && simplifiedLineString . coordinates . length > 0 ) {
795+ if ( simplifiedLineString . coordinates . length > 0 ) {
768796 context . moveTo ( simplifiedLineString . coordinates [ 0 ] [ 0 ] , simplifiedLineString . coordinates [ 0 ] [ 1 ] ) ;
769797 for ( let i = 1 ; i < simplifiedLineString . coordinates . length ; i ++ ) {
770798 context . lineTo ( simplifiedLineString . coordinates [ i ] [ 0 ] , simplifiedLineString . coordinates [ i ] [ 1 ] ) ;
@@ -777,14 +805,21 @@ export class FeatureTiles {
777805 * @param context
778806 * @param featureStyle
779807 * @param boundingBox
808+ * @param transform
780809 */
781- drawLine ( geoJson : any , context : any , featureStyle : FeatureStyle , boundingBox : BoundingBox ) : void {
810+ drawLine (
811+ geoJson : any ,
812+ context : any ,
813+ featureStyle : FeatureStyle ,
814+ boundingBox : BoundingBox ,
815+ transform : Function ,
816+ ) : void {
782817 context . save ( ) ;
783818 context . beginPath ( ) ;
784819 const paint = this . getLinePaint ( featureStyle ) ;
785820 context . strokeStyle = paint . colorRGBA ;
786821 context . lineWidth = paint . strokeWidth ;
787- this . getPath ( geoJson , context , boundingBox ) ;
822+ this . getPath ( geoJson , context , boundingBox , false , transform ) ;
788823 context . stroke ( ) ;
789824 context . closePath ( ) ;
790825 context . restore ( ) ;
@@ -796,6 +831,7 @@ export class FeatureTiles {
796831 * @param context
797832 * @param featureStyle
798833 * @param boundingBox
834+ * @param transform
799835 * @param fill
800836 */
801837 drawPolygon (
@@ -804,6 +840,7 @@ export class FeatureTiles {
804840 context : any ,
805841 featureStyle : FeatureStyle ,
806842 boundingBox : BoundingBox ,
843+ transform : Function ,
807844 fill = true ,
808845 ) : void {
809846 // get paint
@@ -812,13 +849,13 @@ export class FeatureTiles {
812849 if ( ! booleanClockwise ( externalRing . coordinates ) ) {
813850 externalRing . coordinates = externalRing . coordinates . reverse ( ) ;
814851 }
815- this . getPath ( externalRing , context , boundingBox , true ) ;
852+ this . getPath ( externalRing , context , boundingBox , true , transform ) ;
816853 context . closePath ( ) ;
817854 for ( let i = 0 ; i < internalRings . length ; i ++ ) {
818855 if ( booleanClockwise ( internalRings [ i ] . coordinates ) ) {
819856 internalRings [ i ] . coordinates = internalRings [ i ] . coordinates . reverse ( ) ;
820857 }
821- this . getPath ( internalRings [ i ] , context , boundingBox , true ) ;
858+ this . getPath ( internalRings [ i ] , context , boundingBox , true , transform ) ;
822859 context . closePath ( ) ;
823860 }
824861 const fillPaint = this . getPolygonFillPaint ( featureStyle ) ;
@@ -834,28 +871,29 @@ export class FeatureTiles {
834871 }
835872 /**
836873 * Add a feature to the batch
837- * @param simplifyTolerance
838874 * @param geoJson
839875 * @param context
840876 * @param boundingBox
841877 * @param featureStyle
878+ * @param transform
842879 */
843880 async drawGeometry (
844881 geoJson : Geometry ,
845882 context : any ,
846883 boundingBox : BoundingBox ,
847884 featureStyle : FeatureStyle ,
885+ transform : Function ,
848886 ) : Promise < void > {
849887 let i ;
850888 if ( geoJson . type === 'Point' ) {
851- await this . drawPoint ( geoJson , context , boundingBox , featureStyle ) ;
889+ await this . drawPoint ( geoJson , context , boundingBox , featureStyle , transform ) ;
852890 } else if ( geoJson . type === 'LineString' ) {
853- this . drawLine ( geoJson , context , featureStyle , boundingBox ) ;
891+ this . drawLine ( geoJson , context , featureStyle , boundingBox , transform ) ;
854892 } else if ( geoJson . type === 'Polygon' ) {
855893 const converted = PolyToLine ( geoJson ) ;
856894 if ( converted . type === 'Feature' ) {
857895 if ( converted . geometry . type === 'LineString' ) {
858- this . drawPolygon ( converted . geometry , [ ] , context , featureStyle , boundingBox ) ;
896+ this . drawPolygon ( converted . geometry , [ ] , context , featureStyle , boundingBox , transform ) ;
859897 } else if ( converted . geometry . type === 'MultiLineString' ) {
860898 // internal rings
861899 // draw internal rings without fill
@@ -866,12 +904,12 @@ export class FeatureTiles {
866904 coordinates : coords ,
867905 } ;
868906 } ) ;
869- this . drawPolygon ( externalRing , internalRings , context , featureStyle , boundingBox ) ;
907+ this . drawPolygon ( externalRing , internalRings , context , featureStyle , boundingBox , transform ) ;
870908 }
871909 } else {
872910 converted . features . forEach ( feature => {
873911 if ( feature . geometry . type === 'LineString' ) {
874- this . drawPolygon ( feature . geometry , [ ] , context , featureStyle , boundingBox ) ;
912+ this . drawPolygon ( feature . geometry , [ ] , context , featureStyle , boundingBox , transform ) ;
875913 } else if ( feature . geometry . type === 'MultiLineString' ) {
876914 const externalRing = { type : 'LineString' , coordinates : feature . geometry . coordinates [ 0 ] } ;
877915 const internalRings = feature . geometry . coordinates . slice ( 1 ) . map ( coords => {
@@ -880,7 +918,7 @@ export class FeatureTiles {
880918 coordinates : coords ,
881919 } ;
882920 } ) ;
883- this . drawPolygon ( externalRing , internalRings , context , featureStyle , boundingBox ) ;
921+ this . drawPolygon ( externalRing , internalRings , context , featureStyle , boundingBox , transform ) ;
884922 }
885923 } ) ;
886924 }
@@ -894,6 +932,7 @@ export class FeatureTiles {
894932 context ,
895933 boundingBox ,
896934 featureStyle ,
935+ transform ,
897936 ) ;
898937 }
899938 } else if ( geoJson . type === 'MultiLineString' ) {
@@ -906,6 +945,7 @@ export class FeatureTiles {
906945 context ,
907946 featureStyle ,
908947 boundingBox ,
948+ transform ,
909949 ) ;
910950 }
911951 } else if ( geoJson . type === 'MultiPolygon' ) {
@@ -918,11 +958,12 @@ export class FeatureTiles {
918958 context ,
919959 boundingBox ,
920960 featureStyle ,
961+ transform ,
921962 ) ;
922963 }
923964 } else if ( geoJson . type === 'GeometryCollection' ) {
924965 for ( i = 0 ; i < geoJson . geometries . length ; i ++ ) {
925- await this . drawGeometry ( geoJson . geometries [ i ] , context , boundingBox , featureStyle ) ;
966+ await this . drawGeometry ( geoJson . geometries [ i ] , context , boundingBox , featureStyle , transform ) ;
926967 }
927968 }
928969 }
0 commit comments