День добрый. Завис над одной задачей.
Допустим, на странице загружаем какое-либо изображение. На изображении указываем две точки A и B. Координаты точек указываются в пикселях: левое поле ввода - отступ сверху (координата y), правое поле ввода - отступ слева (координата x).
Далее на карте указываем две точки, по которым необходим разместить изображение. Карты использовались
OpenStreetMap, выводятся через библиотеку
LeafLet.
Здесь координаты указываются в градусах.
Далее, изображение загружается поверх карты. Точки на изображении должны совпасть с точками на карте. Точки совпадают, но изображение растягивается.
Пока что добился такого варианта.
Для размещения изображения использовал самописную формулу:
Ax - x точки А на изображении; Ay - y точки А на изображении
Bx - x точки B на изображении; By - y точки А на изображении
Agx - x точки А на карте (долгота); Agy - y точки А на карте (широта)
Bgx - x точки B на карте (долгота); Bgy - y точки B на карте (широта)
W - ширина изображения; H - высота изображения
Находим дельту точек A и B по x (на изображении):
ABX = Ax - Bx
Находим дельту точек A и B по y (на изображении):
ABY = Ay - By
Находим дельту точек A и B по x (на карте):
ABGX = Agx - Bgx
Находим дельту точек A и B по y (на карте):
ABGY = Agy - Bgy
Находим координаты точек:
GX1 = (0 - Ax) * ABGX / ABX + Agx
GX2 = GX3 = (W - Ax) * ABGX / ABX + Agx
GY1 = GY2 = (0 - Ay) * ABGY / ABY + Agy
GY3 = (H - Ay) * ABGY / ABY + Agy
GX3 и GY3 - дополнительные координаты. В принципе, их можно не учитывать. Нужны для разворачивания изображения на карте.
Вот, собственно, примерный код:
//отображение изображения по координатам из файла data_file_map.json (в файле содержатся данные координат)
$.ajax({
url: '/uploads/data_file_map.json',
dataType: 'json',
success: function (data) {
//координаты, по которым выстраивается изображение
var bounds = [[data.map_lat1, data.map_lng1], [data.map_lat2, data.map_lng2], [data.map_lat3, data.map_lng3]];
//создание слоя для изображения
var image_layer = L.imageOverlay('/uploads/'+data.fileName, bounds, {opacity:0.4});
//добавление слоя на карте
image_layer.addTo(map);
}
});
//получение данных изображения из data_image_param.json
$.ajax({
url: '/uploads/data_image_param.json',
dataType: 'json',
success: function (data) {
//координаты точек на карте
var lat1 = $('#lat1').val(),
lat2 = $('#lat2').val(),
lat3 = $('#lat3').val(),
lng1 = $('#lng1').val(),
lng2 = $('#lng2').val(),
lng3 = $('#lng3').val();
//данные изображения
var x1 = 0,
y1 = 0,
px1 = data.lng1, //x точки A
py1 = data.lat1, //y точки A
px2 = data.lng2, //x точки B
py2 = data.lat2, //y точки B
img_width = data.imgWidth, //ширина изображения
img_height = data.imgHeight; //высота изображения
var dpx = parseInt(px1) - parseInt(px2); //x точки А минус x точки B (на изображении)
var dpy = parseInt(py1) - parseInt(py2); //y точки А минус y точки B (на изображении)
var dpgx = lng1 - lng2; //долгота точки A минус долгота точки B (на карте)
var dpgy = lat1 - lat2; //широта точки A минус широта точки B (на карте)
//находим координаты для точек
var gx1 = (0 - px1) * dpgx / dpx + parseFloat(lng1);
var gx3 = (img_width - px1) * dpgx / dpx + parseFloat(lng1);
var gy1 = (0 - py1) * dpgy / dpy + parseFloat(lat1);
var gy3 = (img_height - py1) * dpgy / dpy + parseFloat(lat1);
var gx2 = gx3;
var gy2 = gy1;
//gx3 и gy3 нужны для корректного отображения изображения на карте (так требует leaflet, иначе изображение отобржается не так как надо)
//полученные данные (gx1, gx2, gx3, gy1, gy2, gy3) сохраняются, допустим, в файл data_file_map.json, который используется для отображения изображения на карте
/*
.....
*/
}
});
По итогу, изображение должно размещаться точно по точкам с сохранением своих пропорций и, если необходимо, с углом наклона. Как здесь:
Собственно, и возникает вопрос:
как задать точные размеры и определить угол наклона, чтобы добиться совпадения по точкам, не нарушая пропорции изображения?
P.S.
Для нахождения угла попробовал следующий вариант.
Загрузил изображение. Изображение растянулось по точкам. Нашел длину отрезков между точками A и B и на изображении и на карте. Определил процент разности между отрезками. При помощи этого процента задал ширину для изображения. Получилось изображение с сохраненными пропорциями.
Далее, чтобы рассчитать угол поворота определил "воображаемый" треугольник между точкам A, B (изображение) и B (карта).
Написал функцию, чтобы рассчитать арккосинус, наподобие этой:
//арккосинус A
function getAcosA(a, b, c) {
var arccos, angle;
arccos = (a*a + c*c - b*b)/(2*a*c);
angle = Math.acos(arccos);
return (angle*180)/Math.PI;
}
Угол рассчитывает, но довольно не точный.