Search code examples
react-nativesvgmapsmapboxpolyline

How to draw Polyline without rendering map using coordinates


I have array of coordinates and I can draw polyline on map using theese coordinates without problem.

Now what I want to do is, only drawing a polyline to screen without rendering the map.

Below is first few items of my coordinates array:

[
            [6.56674, 45.39881],
            [6.56682, 45.399],
            [6.56701, 45.39959],
            [6.56727, 45.40006],
            [6.56738, 45.4003],
            [6.56745, 45.40041],
            [6.56757, 45.40053]
]

Drawen polyline on the map

I want to draw the same polyline to black background without rendering map.

I tried to draw svg polyline using the array of coordinates but I couldn't achieved what I wanted only a dot appeared on the screen. Didn't draw a polyline.

import {Svg, Polyline} from 'react-native-svg';

<Svg height="100" width="100">
        <Polyline
          points={MY_ARRAY_OF_COORDS.map(item => `${item[0]},${item[1]`).join(" ")}
          fill="none"
          stroke="blue"
          strokeWidth="5"
          strokeLinecap="round"
          strokeLinejoin="round"
        />
</Svg>

Solution

  • The <polyline> is actually rendered but almost invisible since the coordinates are very close to each other.

    So you need to calculate a scale factor.

    Js example

    const coords= [
                [6.56674, 45.39881],
                [6.56682, 45.399],
                [6.56701, 45.39959],
                [6.56727, 45.40006],
                [6.56738, 45.4003],
                [6.56745, 45.40041],
                [6.56757, 45.40053]
    ];
    
    //calculate coordinate range for a scale factor
    let xArr = coords.map((val)=>{return val[0]} );
    let xMin = Math.min(...xArr);
    let xMax = Math.max(...xArr);
    let yArr = coords.map((val)=>{return val[1]} );
    let yMin = Math.min(...yArr);
    let yMax = Math.max(...yArr);
    
    let xRange = xMax- xMin;
    let yRange = yMax- yMin;
    let scale = 100/Math.max(...[xRange, yRange]);
    //console.log(xRange, yRange, scale)
    
    
    //scale coordinates
    coords.forEach(function(coord){
      let [x,y] =[coord[0], coord[1]];
      coord[0] = (x-xMin)*scale;
      coord[1] = (y-yMin)*scale;
    })
    
    //draw polyline
    const svg = document.querySelector('svg');
    const polyline = svg.querySelector('polyline');
    polyline.setAttribute('points', coords.join());
    svg{
      border: 1px solid #ccc;
      overflow:visible
    }
    <svg height="100" width="100">
            <polyline
              points=""
              fill="none"
              stroke="blue"
              strokeWidth="10"
              strokeLinecap="round"
              strokeLinejoin="round"
            />
    </svg>

    First we need to calculate ranges for x and y values (so the maximum distances between maximum and minimum x).

    let xRange = xMax- xMin; //0.000829999999999664
    let yRange = yMax- yMin; //0.001720000000005939
    

    If you need a svg bounding box of 100x100 units the scaling factor would be:

    let scale = 100/Math.max(...[xRange, yRange]);
    

    Eventually we need to subtract the minimum x and y offsets to align the polyline to the x/y axes origin.