1

It is possible to get the coordinates of the four corners of the image, given the center of the image coordinate? or the bottom left and upper right corners?

Currently, I am center the map in the lat/long mentioned above and I want to display the image in that coordinates.

Example Code

import Map from 'ol/Map.js';
import View from 'ol/View.js';
import Projection from 'ol/proj/Projection.js';
import { getCenter } from 'ol/extent.js';
import ImageLayer from 'ol/layer/Image.js';
import Static from 'ol/source/ImageStatic.js';
import TileLayer from 'ol/layer/Tile'
import OSM from 'ol/source/OSM.js';

var osmSource = new OSM();
var extent = [0, 0, 4000, 3000];
var mapLayer = new TileLayer({
    source: osmSource,
    projection: new Projection(
      { 
          code: 'EPSG:3857', 
          units: 'm', 
          axisOrientation: 'neu',
          global: false 
      }),
      center : getCenter(extent)
  })

var map = new Map({
    layers: [
        mapLayer,

        new ImageLayer({
            source: new Static({
                attributions: '© <a href="https://dronemapper.com/sample_data/">dronemapper</a>',
                url: './data/DJI_0014.JPG',
                // projection: projection,
                imageExtent: extent
            })
        })
    ],
    target: 'map-container',
    view: new View({
        // projection: projection,
        center: getCenter(extent),
        zoom: 2,
        maxZoom: 8
    }),
    projection: 'EPSG:3857'
});

As you can see the image is displayed in 0,0 (Guinea gulf), I'm trying to get the coordinates for bottom-left and right-up to display the image in the coordinates provided by the image.

PS: image info: 4000 x 3000 pixels lat 38: 47: 40.98290000 lon 108: 1: 16.25819999


I have a working example with the image placed in the right coordinates, now I would need some directives to get the right zoom and rotation the image to match the road on the map.

Tip: the image if from here https://dronemapper.com ©, image DJI_0014.JPG

import Map from 'ol/Map.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/Tile'
import OSM from 'ol/source/OSM.js';
import { Vector as VectorLayer } from 'ol/layer.js';
import { Icon, Style } from 'ol/style.js';
import VectorSource from 'ol/source/Vector.js';
import Feature from 'ol/Feature.js';
import Point from 'ol/geom/Point.js';
import { transform } from 'ol/proj';

function photoStyle(feature, scale) {
    var url = feature.get('url');
    return new Style({
        image: new Icon({
            scale: scale,
            src: url
        })
    });
}

function imgStyle(feature) {
    return [photoStyle(feature, 0.10)];
}

var layer = new TileLayer({
    source: new OSM()
});

var imgSource = new VectorSource();

var imgLayer = new VectorLayer({
   // extent: [0, 0, 4000, 3000],
    source: imgSource,
    style: imgStyle
    // ,
    // rotation: Math.PI / 6
});

//Photo coordinates   38.79471747, -108.02111111 var extent = [0, 0, 4000, 3000];

var feature = new Feature();
feature.set('url', './data/DJI_0014.JPG');
var coordinate = transform([-108.02111111, 38.79471747], 'EPSG:4326', 'EPSG:3857');
var geometry = new Point(coordinate);
feature.setGeometry(geometry);
imgSource.addFeature(feature)

var map = new Map({

    target: 'map-container',
    view: new View({

        center: coordinate,
        zoom: 19

    })

});

map.addLayer(layer);
map.addLayer(imgLayer);

You Can use [ALT] + [Shift] + Click to rotate the map. I would like to display the image rotated and zoomed to the right position.

What I want

enter image description here

What I have

enter image description here

  • Add an info display to your map to display the resolution and rotation, and reduce the zoom factor so you can fine tune the resolution(e.g. using the 4th root of 2 give 4 times as many zoom levels as the default of 2 which simply doubles the scale at each zoom level) codesandbox.io/s/simple-rs8zn When testing with a 10% scale image the best resolution for that image seems to be about 0.6 (the full scale image would be different) and view rotation is about -1.54 (the view rotation to fit the image is the negative of the image rotation you would need) – Mike Aug 17 '19 at 13:44
  • Applying that to the image style gives codesandbox.io/s/simple-vdprw – Mike Aug 17 '19 at 13:44
  • @Mike I owe you a beer and a barbecue!! You save my day (or week) thank you very much, man. I really appreciate your time to help me! – Santiago Salaberry Aug 19 '19 at 11:17
1

You cannot get the extent from the center and number of pixels alone. These images all have the same center and number of pixels:

enter image description here enter image description here enter image description here

You also need to know the resolution (the distance on the ground covered by each pixel) and the rotation (was the image taken with north at the top)

| improve this answer | |
  • Do you know if the required data is in the image exif data? Especially the rotation and resolution. Btw, Do you know how to put the imagen in the coordinates? Meanwhile, I'll try to figure out how to solve the resolution/rotation issue. Thanks in advance – Santiago Salaberry Aug 15 '19 at 19:12
1

Solved by Mike Mike's solution here Thanks to @Mike to his help. I put the solution that Mike did in codesandbox (just in case, in a future may not be available)

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Simple Map</title>
    <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
    <style>
      .map {
        width: 100%;
        height:400px;
      }
    </style>
  </head>
  <body>
    <div id="map-container" class="map"></div>
    <script src="index.js"></script>
  </body>
</html>

Index.js

import "ol/ol.css";
import Map from "ol/Map.js";
import View from "ol/View.js";
import TileLayer from "ol/layer/Tile";
import OSM from "ol/source/OSM.js";
import { Vector as VectorLayer } from "ol/layer.js";
import { Icon, Style } from "ol/style.js";
import VectorSource from "ol/source/Vector.js";
import Feature from "ol/Feature.js";
import Point from "ol/geom/Point.js";
import { transform } from "ol/proj";

function photoStyle(feature, scale) {
  var url = feature.get("url");
  return new Style({
    image: new Icon({
      scale: scale,
      src: url,
      rotation: 1.54
    })
  });
}

function imgStyle(feature, resolution) {
  return [photoStyle(feature, 0.6 / resolution)];
}

var layer = new TileLayer({
  source: new OSM()
});

var imgSource = new VectorSource();

var imgLayer = new VectorLayer({
  // extent: [0, 0, 4000, 3000],
  source: imgSource,
  style: imgStyle
  // ,
  // rotation: Math.PI / 6
});

//Photo coordinates   38.79471747, -108.02111111 var extent = [0, 0, 4000, 3000];

var feature = new Feature();
feature.set("url", "https://i.stack.imgur.com/sylFt.jpg");
var coordinate = transform(
  [-108.02111111, 38.79471747],
  "EPSG:4326",
  "EPSG:3857"
);
var geometry = new Point(coordinate);
feature.setGeometry(geometry);
imgSource.addFeature(feature);

var map = new Map({
  target: "map-container",
  view: new View({
    center: coordinate,
    zoom: 17
  })
});

map.addLayer(layer);
map.addLayer(imgLayer);
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.