Страница 1 из 1

leaflet или openlayers как движок карты для любого растра?

Добавлено: 11 мар 2014, 17:17
semasping
Добрый день, Уважаемые!
Можно ли с помощью библиотек leaflet или openlayers реализовать поставленную ниже задачу? Или нужно что-то другое

Задача: сделать интерактивную карту объекта с возможностью масштабирования и адресацией на элементы объекта Карта должна отображаться на html страницах.

Подробнее о результате на примере: Eсть растровая схема дома. В итоге должна получится карта:
- с возможностью приближения-удаления этой схемы дома,
- возможностью кликнуть(тапнуть) на любую комнату - pop up с информацией о комнате, ссылкой на другую страницу.
- с другой страницы перейти обратно к карте, к любой комнате.

Растровую схему нарезаем на тайлы размером 256px под несколько масштабов.
По начальной растровой схеме в программе josm делаем osm разметку:
- границы растровой карты заданы с помощью прямоугольника с неким тегом, например imageBounds=true
- каждая комната - объект с тегом idObj
- внутри объекта - точка в которой отображается маркер. Точка имеет тег idPoint

Можно ли с помощью библиотек leaflet или openlayers реализовать поставленную выше задачу? Как обращаться к объектам в osm и geojson?
Если это все реально - то согласен ли кто-нибудь проконсультировать (стоимость?) или реализовать подобное (цена?)

Собственные пробы:
1. При использовании Leaflet:
- подключаем тайлы
- подключаем geojson
и они не совпадают !!!
Тайлы подключаются, но выходит, что 0 масштаб - это весь мир. Но удается вызвать popup с идентификатором объектов, значит и ссылки можно будет вставить.
Если бы удалось совместить разные слои - то это было бы возможно лучшим вариантом.

2. При использовании openlayers:
- получилось совместить тайлы и osm
- если задавать значально var mapBounds = new OpenLayers.Bounds(37.713246, 55.91410447548679, 37.717452, 55.915370530099466);
- но не понятно как взять из osm разметки идентификаторы комнат и вообще как работать с данными в osm;
- хотелось бы не вручную задавать эти координаты, а получить их из osm или geojson файла (так как в разметке они существуют как вершины прямоугольника с неким тегом например "imageBounds")

результаты собственных проб можно посмотреть по ссылкам:
Leaflet_1
Leaflet_2


openlayers_with_osm_1 -

openlayers_with_osm_2 -

1 и 2 отличаются нарезками тайлов. Нарезка выполнялась в программе MapTiler. Там есть возможность задать координаты соответствия углов картины углам в мире.

Если необходимо все исходники можно найти на https://github.com/semasping/forQuestAboutHouseMap

Большое спасибо за возможную помощь и внимание.

Re: leaflet или openlayers как движок карты для любого растр

Добавлено: 12 мар 2014, 13:53
Denis Rykov
Посмотрите мою статью. Там помимо всего прочего есть ссылки на примеры, которые похожи на то, что вам нужно.

Re: leaflet или openlayers как движок карты для любого растр

Добавлено: 12 мар 2014, 15:47
semasping
Denis Rykov писал(а):Посмотрите мою статью. Там помимо всего прочего есть ссылки на примеры, которые похожи на то, что вам нужно.
Спасибо. Статья очень интересная. Натолкнула на несколько мыслей фразой
Отметим, что проекция объекта карты выставлена в значение L.CRS.Simple. Согласно документации, именно это значение используется в случае опубликования изображений, не имеющих географической привязки.
Возник вопрос :
Тогда какую проекцию нужно тогда выставлять в редакторе josm чтобы можно было совместить с разметкой из osm или geojson файла?

Re: leaflet или openlayers как движок карты для любого растр

Добавлено: 12 мар 2014, 21:01
ericsson
А разве JOSM умеет экспортировать вектор в чем-то кроме OSM XML с координатами в виде широты/долготы WGS84?

Re: leaflet или openlayers как движок карты для любого растр

Добавлено: 12 мар 2014, 21:38
semasping
Насколько я понимаю экспортируемые координаты зависят от настроек самого редактора
В самом osm файле упоминания о проекции нет, но координаты узлов отличаются при разных проекциях.
В настройках во вложении указал где откопал смену проекций

Re: leaflet или openlayers как движок карты для любого растр

Добавлено: 12 мар 2014, 23:12
ericsson
Вот прямо сейчас поменял Map Projection на UTM соответствующей зоны, сохранил в json и в xml - везде градусы. JOSM последний стабильный 6891. По-моему, эта настройка относится к проекции рабочего пространства и не влияет на экспорт.
Если вы собираетесь совмещать план с реальной картой, то делать его нужно в реальных координатах - та фраза про L.CRS.Simple относится к ситуации, когда у вас только план, который сделан в координатах "от угла здания". Какую при этом реальную систему координат выбрать - не особенно важно, потому что данные можно перепроецировать налету. Хотя конечно, если работаете с OSM, проще остановиться на EPSG:900913 либо EPSG:3857. Вообще, самый простейший способ, требующий минимум программирования и понимания проекций - использовать Leaflet и KML plugin к нему, а планы делать в KML (то, что нужно показать внутри popup, просто кладется в виде HTML внутрь <description>)

Re: leaflet или openlayers как движок карты для любого растр

Добавлено: 11 сен 2014, 15:49
Kamur
Посмотрите, может пригодится: Canvas. Исходник http://phrogz.net.

Код: Выделить всё

<!DOCTYPE HTML>
<html lang="en"><head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<title>Zooming via HTML5 Canvas Context</title>
	<style type="text/css" media="screen">
		body { background:#eee; margin:1em; text-align:center; }
		canvas { display:block; margin:1em auto; background:#fff; border:1px solid #ccc }
	</style>
</head><body>

<canvas></canvas>
<p id="footer"> </p>
<script type="text/javascript" charset="utf-8">
	var canvas = document.getElementsByTagName('canvas')[0];
	canvas.width = 800; canvas.height = 600;
	var gkhead = new Image;
	var ball   = new Image;
	window.onload = function(){		
		var ctx = canvas.getContext('2d');
		trackTransforms(ctx);
		function redraw(){
			// Clear the entire canvas - Очистить весь холст
			var p1 = ctx.transformedPoint(0,0);
			var p2 = ctx.transformedPoint(canvas.width,canvas.height);
			ctx.clearRect(p1.x,p1.y,p2.x-p1.x,p2.y-p1.y);

			// Alternatively:
			// ctx.save();
			// ctx.setTransform(1,0,0,1,0,0);
			// ctx.clearRect(0,0,canvas.width,canvas.height);
			// ctx.restore();

			ctx.drawImage(gkhead,200,50);

			ctx.beginPath();
			ctx.lineWidth = 6;
			ctx.moveTo(399,250);
			ctx.lineTo(474,256);
			ctx.stroke();

			ctx.save();
			ctx.translate(4,2);
			ctx.beginPath();
			ctx.lineWidth = 1;
			ctx.moveTo(436,253);
			ctx.lineTo(437.5,233);
			ctx.stroke();

			ctx.save();
			ctx.translate(438.5,223);
			ctx.strokeStyle = '#06c';
			ctx.beginPath();
			ctx.lineWidth = 0.05;
			for (var i=0;i<60;++i){
				ctx.rotate(6*i*Math.PI/180);
				ctx.moveTo(9,0);
				ctx.lineTo(10,0);
				ctx.rotate(-6*i*Math.PI/180);
			}
			ctx.stroke();
			ctx.restore();

			ctx.beginPath();
			ctx.lineWidth = 0.2;
			ctx.arc(438.5,223,10,0,Math.PI*2);
			ctx.stroke();
			ctx.restore();
			
			ctx.drawImage(ball,379,233,40,40);
			ctx.drawImage(ball,454,239,40,40);
			ctx.drawImage(ball,310,295,20,20);
			ctx.drawImage(ball,314.5,296.5,5,5);
			ctx.drawImage(ball,319,297.2,5,5);
		}
		redraw();
		
		var lastX=canvas.width/2, lastY=canvas.height/2;
		var dragStart,dragged;
		canvas.addEventListener('mousedown',function(evt){
			document.body.style.mozUserSelect = document.body.style.webkitUserSelect = document.body.style.userSelect = 'none';
			lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
			lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
			dragStart = ctx.transformedPoint(lastX,lastY);
			dragged = false;
		},false);
		canvas.addEventListener('mousemove',function(evt){
			lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
			lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
			dragged = true;
			if (dragStart){
				var pt = ctx.transformedPoint(lastX,lastY);
				ctx.translate(pt.x-dragStart.x,pt.y-dragStart.y);
				redraw();
			}
		},false);
		canvas.addEventListener('mouseup',function(evt){
			dragStart = null;
			if (!dragged) zoom(evt.shiftKey ? -1 : 1 );
		},false);

		var scaleFactor = 1.1;
		var zoom = function(clicks){
			var pt = ctx.transformedPoint(lastX,lastY);
			ctx.translate(pt.x,pt.y);
			var factor = Math.pow(scaleFactor,clicks);
			ctx.scale(factor,factor);
			ctx.translate(-pt.x,-pt.y);
			redraw();
		}

		var handleScroll = function(evt){
			var delta = evt.wheelDelta ? evt.wheelDelta/40 : evt.detail ? -evt.detail : 0;
			if (delta) zoom(delta);
			return evt.preventDefault() && false;
		};
		canvas.addEventListener('DOMMouseScroll',handleScroll,false);
		canvas.addEventListener('mousewheel',handleScroll,false);
	};
	gkhead.src = 'PX0HCWGB.jpg';
	ball.src   = 'http://phrogz.net/tmp/alphaball.png';
	
	// Adds ctx.getTransform() - returns an SVGMatrix
	// Adds ctx.transformedPoint(x,y) - returns an SVGPoint
	function trackTransforms(ctx){
		var svg = document.createElementNS("http://www.w3.org/2000/svg",'svg');
		var xform = svg.createSVGMatrix();
		ctx.getTransform = function(){ return xform; };
		
		var savedTransforms = [];
		var save = ctx.save;
		ctx.save = function(){
			savedTransforms.push(xform.translate(0,0));
			return save.call(ctx);
		};
		var restore = ctx.restore;
		ctx.restore = function(){
			xform = savedTransforms.pop();
			return restore.call(ctx);
		};

		var scale = ctx.scale;
		ctx.scale = function(sx,sy){
			xform = xform.scaleNonUniform(sx,sy);
			return scale.call(ctx,sx,sy);
		};
		var rotate = ctx.rotate;
		ctx.rotate = function(radians){
			xform = xform.rotate(radians*180/Math.PI);
			return rotate.call(ctx,radians);
		};
		var translate = ctx.translate;
		ctx.translate = function(dx,dy){
			xform = xform.translate(dx,dy);
			return translate.call(ctx,dx,dy);
		};
		var transform = ctx.transform;
		ctx.transform = function(a,b,c,d,e,f){
			var m2 = svg.createSVGMatrix();
			m2.a=a; m2.b=b; m2.c=c; m2.d=d; m2.e=e; m2.f=f;
			xform = xform.multiply(m2);
			return transform.call(ctx,a,b,c,d,e,f);
		};
		var setTransform = ctx.setTransform;
		ctx.setTransform = function(a,b,c,d,e,f){
			xform.a = a;
			xform.b = b;
			xform.c = c;
			xform.d = d;
			xform.e = e;
			xform.f = f;
			return setTransform.call(ctx,a,b,c,d,e,f);
		};
		var pt  = svg.createSVGPoint();
		ctx.transformedPoint = function(x,y){
			pt.x=x; pt.y=y;
			return pt.matrixTransform(xform.inverse());
		}
	}
</script>
</body></html>