在canvas上进行绘图,实现要素配准
生活随笔
收集整理的這篇文章主要介紹了
在canvas上进行绘图,实现要素配准
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
由于要求上采用Html來實現配準的畫圖功能(如果直接采用超圖的接口、ArcGIS js API等會簡單很多),所以有如下思路:地圖采用了超圖的接口,獲取其已經發布的服務,地圖顯示在一個Div中,在地圖上方疊加一個Canvas進行畫圖。所畫圖形經過平移旋轉(縮放會有問題)后,配準地圖上的要素,然后將屏幕坐標轉換為地圖坐標,得到配準結果。(此配準不是完全的影像配準,其過程有要求:所畫圖形不能發生形變)。
JS 和html 沒有做分離,所有代碼如下,有時間再回來編輯:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">
<head>
? ? <title>第5個測試頁面</title>
? ? <style type="text/css">
? ? ? ? *
? ? ? ? {
? ? ? ? ? ? margin: 0 0 0 0;
? ? ? ? ? ? padding: 0 0 0 0;
? ? ? ? }
? ? ? ? body
? ? ? ? {
? ? ? ? ? ? overflow:auto;
? ? ? ? ? ? background: #fff;
? ? ? ? }
? ? ? ? #map, #canvasOne
? ? ? ? {
? ? ? ? ? ? position: absolute;
? ? ? ? ? ? width: 1000px;
? ? ? ? ? ? height: 1000px;
? ? ? ? ? ? top: 20px;
? ? ? ? ? ? left: 30px;
? ? ? ? }
? ? ? ? #rightdiv
? ? ? ? {
? ? ? ? ? ? position:absolute;
? ? ? ? ? ? top:20px;
? ? ? ? ? ? left:1060px;
? ? ? ? ? ? width: 380px;
? ? ? ? ? ? height: 1000px;
? ? ? ? ? ? display: inline-block;
? ? ? ? ? ? overflow: hidden;
? ? ? ? }
? ? ? ? #FirstFloorDiv, #SecondFloorDiv
? ? ? ? {
? ? ? ? ? ? display: inline-block;
? ? ? ? }
? ? </style>
? ? <script type="text/javascript" src="libs/SuperMap.Include.js"></script>
? ? <script type="text/javascript">
? ? ? ? ///Canvas的所有畫圖功能
? ? ? ? var JsonString = false; ? ? ? //記錄Json的字符串(原始)
? ? ? ? var Coordinates = false; ? ? ?//記錄Json解析出來的坐標串(原始)
? ? ? ? var Rectangle = false; ? ? ? ?//記錄外包矩形框(原始)[minX, minY, maxX, maxY]
? ? ? ? var Circle = false; ? ? ? ?//記錄外包圓形(原始)[Center,Radius];Center:X,Y;
? ? ? ? var canvas = false;
? ? ? ? var Before_Coordinates = false;
? ? ? ? var After_Coordinates = false;
? ? ? ? var Point_FirstSelect = false;
? ? ? ? var Point_FirstSelect_index = false;
? ? ? ? var Point_SecondSelect = false;
? ? ? ? var Point_SecondSelect_index = false;
? ? ? ? var SwitchCase = 1; ? ? ? ? //默認為平移
? ? ? ? var isOpenPan = 1; ? ? ? ? ? //是否為平移
? ? ? ? var isOpenRotate = 2; ? ? ? ? ? //是否為旋轉
? ? ? ? var thelta = false; //旋轉角
? ? ? ? var banjing = 80; ? ? ? ? ? ? ? ? ?//縮放比例半徑
? ? ? ? var MapCenter = { X: 550, Y: 350 };//縮放平移的地圖中心位置
? ? ? ? //解析Json格式,返回Building坐標數組
? ? ? ? function AnalyzeJson2Cos(JsonString) {
? ? ? ? ? ? var obj = eval('(' + JsonString + ')');
? ? ? ? ? ? return obj.Building.Coordinates;
? ? ? ? }
? ? ? ? //計算坐標串的外包矩形
? ? ? ? function CompRectangle(Cos) {
? ? ? ? ? ? var minX = Cos[0].X;
? ? ? ? ? ? var minY = Cos[0].Y;
? ? ? ? ? ? var maxX = Cos[0].X;
? ? ? ? ? ? var maxY = Cos[0].Y;
? ? ? ? ? ? for (var i = 1; i < Cos.length; i++) {
? ? ? ? ? ? ? ? if (Cos[i].X > maxX) maxX = Cos[i].X;
? ? ? ? ? ? ? ? if (Cos[i].X < minX) minX = Cos[i].X;
? ? ? ? ? ? ? ? if (Cos[i].Y > maxY) maxY = Cos[i].Y;
? ? ? ? ? ? ? ? if (Cos[i].Y < minY) minY = Cos[i].Y;
? ? ? ? ? ? }
? ? ? ? ? ? Rectangle = { minX: minX, minY: minY, maxX: maxX, maxY: maxY };
? ? ? ? ? ? return Rectangle;
? ? ? ? }
? ? ? ? //計算坐標串的外包圓形
? ? ? ? function CompCircle(Rectangle) {
? ? ? ? ? ? var Center = { X: (Rectangle.maxX - Rectangle.minX) + Rectangle.minX, Y: (Rectangle.maxY - Rectangle.minY) + Rectangle.minY };
? ? ? ? ? ? var Radius = 0.5 * Math.sqrt((Rectangle.maxX - Rectangle.minX) * (Rectangle.maxX - Rectangle.minX) + (Rectangle.maxY - Rectangle.minY) * (Rectangle.maxY - Rectangle.minY));
? ? ? ? ? ? Circle = { Center: Center, Radius: Radius };
? ? ? ? ? ? return Circle;
? ? ? ? }
? ? ? ? //計算兩點距離
? ? ? ? function CompDistance(P1, P2) {
? ? ? ? ? ? return Math.sqrt((P1.X - P2.X) * (P1.X - P2.X) + (P1.Y - P2.Y) * (P1.Y - P2.Y));
? ? ? ? }
? ? ? ? //計算兩點構成的直線與正北方向的夾角
? ? ? ? function ComputeAngle(FPoint, LPoint) {
? ? ? ? ? ? var dRotateAngle;
? ? ? ? ? ? if (FPoint.Y === LPoint.Y) {
? ? ? ? ? ? ? ? if (FPoint.X < LPoint.X) { dRotateAngle = Math.PI / 2; }
? ? ? ? ? ? ? ? else { dRotateAngle = Math.PI / 2 * 3; }
? ? ? ? ? ? ? ? return dRotateAngle;
? ? ? ? ? ? }
? ? ? ? ? ? else {
? ? ? ? ? ? ? ? var deltX = Math.abs(FPoint.X - LPoint.X);
? ? ? ? ? ? ? ? var deltY = Math.abs(FPoint.Y - LPoint.Y);
? ? ? ? ? ? ? ? dRotateAngle = Math.atan(deltX / deltY);
? ? ? ? ? ? }
? ? ? ? ? ? var PI = Math.PI;
? ? ? ? ? ? //如果下一點的橫坐標大于前一點(在第一和第四象限)
? ? ? ? ? ? if (LPoint.X >= FPoint.X) {
? ? ? ? ? ? ? ? //在第一象限(0<=dRotateAngle<=90)
? ? ? ? ? ? ? ? if (LPoint.Y <= FPoint.Y) {
? ? ? ? ? ? ? ? ? ? dRotateAngle = dRotateAngle;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else {
? ? ? ? ? ? ? ? ? ? dRotateAngle = PI - dRotateAngle;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? else//(在第二和第三象限)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (LPoint.Y <= FPoint.Y) {
? ? ? ? ? ? ? ? ? ? dRotateAngle = 2 * PI - dRotateAngle;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else {
? ? ? ? ? ? ? ? ? ? dRotateAngle = PI + dRotateAngle;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? return dRotateAngle;
? ? ? ? }
? ? ? ? //一個簡單的莫卡托轉經緯度
? ? ? ? function Mercator2lonLat(mercator) {
? ? ? ? ? ? var lonLat = { X: 0, Y: 0 };
? ? ? ? ? ? var x = mercator.X / 20037508.34 * 180;
? ? ? ? ? ? var y = mercator.Y / 20037508.34 * 180;
? ? ? ? ? ? y = 180 / Math.PI * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2);
? ? ? ? ? ? lonLat.X = x;
? ? ? ? ? ? lonLat.Y = y;
? ? ? ? ? ? alert(lonLat.X);
? ? ? ? ? ? return lonLat;
? ? ? ? }
//將所有坐標縮放到地圖中心位置(目前是通過外包圓中心進行縮放,這樣會導致某些問題,下一步考慮是否采用坐標原點進行縮放)
function ZoomSystem(objCoords) {
? ?var objCircle = CompCircle(CompRectangle(objCoords));
? ?//進行縮放,對所有坐標進行縮放 要分四個象限去算
? ?var scale = banjing / objCircle.Radius;
? ?if (scale > 1.5 || scale < 0.5) {
? ? ? ?for (var i = 0; i < Coordinates.length; i++) {
? ? ? ? ? ?var length = CompDistance(objCircle.Center, objCoords[i]);
? ? ? ? ? ?var NorthAngle = ComputeAngle(objCircle.Center, objCoords[i]);
? ? ? ? ? ?if (objCoords[i].X > objCircle.Center.X) {
? ? ? ? ? ? ? ?objCoords[i].X -= Math.abs(length * (1 - scale) * Math.sin(NorthAngle));
? ? ? ? ? ? ? ?if (objCoords[i].Y > objCircle.Center.Y) {
? ? ? ? ? ? ? ? ? ?objCoords[i].Y -= Math.abs(length * (1 - scale) * Math.cos(NorthAngle));
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?else {
? ? ? ? ? ? ? ? ? ?objCoords[i].Y += Math.abs(length * (1 - scale) * Math.cos(NorthAngle));
? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ? ? ?else {
? ? ? ? ? ? ? ?objCoords[i].X += Math.abs(length * (1 - scale) * Math.sin(NorthAngle));
? ? ? ? ? ? ? ?if (objCoords[i].Y > objCircle.Center.Y) {
? ? ? ? ? ? ? ? ? ?objCoords[i].Y -= Math.abs(length * (1 - scale) * Math.cos(NorthAngle));
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?else {
? ? ? ? ? ? ? ? ? ?objCoords[i].Y += Math.abs(length * (1 - scale) * Math.cos(NorthAngle));
? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?objCircle = CompCircle(CompRectangle(objCoords));
? ?}
? ?//平移到MapCenter
? ?var deltX = objCircle.Center.X - MapCenter.X;
? ?var deltY = objCircle.Center.Y - MapCenter.Y;
? ?for (var i = 0; i < Coordinates.length; i++) {
? ? ? ?objCoords[i].X -= deltX;
? ? ? ?objCoords[i].Y -= deltY;
? ?}
? ?return objCoords;
}
//在Canvas界面上畫出 原始 圖形
function drawJson() {
? ? ? ? ? ? //獲取Json序列中的坐標串
? ? ? ? ? ? JsonString = document.getElementById('Jsontxt').value;
? ? ? ? ? ? Coordinates = AnalyzeJson2Cos(JsonString);
? ? ? ? ? ? //獲取待操作的坐標數組
? ? ? ? ? ? Before_Coordinates = copyObject(ZoomSystem(Coordinates));
? ? ? ? ? ? After_Coordinates = copyObject(ZoomSystem(Coordinates));
? ? ? ? ? ? //初始化canvas進行畫圖
? ? ? ? ? ? var canvas = document.getElementById("canvasOne");
? ? ? ? ? ? //簡單地檢測當前瀏覽器是否支持Canvas對象,以免在一些不支持html5的瀏覽器中提示語法錯誤
? ? ? ? ? ? if (canvas.getContext) {
? ? ? ? ? ? ? ? //獲取對應的CanvasRenderingContext2D對象(畫筆)
? ? ? ? ? ? ? ? var ctx = canvas.getContext("2d");
? ? ? ? ? ? ? ? //開始一個新的繪制路徑
? ? ? ? ? ? ? ? ctx.beginPath();
? ? ? ? ? ? ? ? ctx.strokeStyle = "blue";
? ? ? ? ? ? ? ? //設置路徑起點坐標
? ? ? ? ? ? ? ? ctx.moveTo(Coordinates[0].X, Coordinates[0].Y);
? ? ? ? ? ? ? ? for (var i = 1; i < Coordinates.length; i++) {
? ? ? ? ? ? ? ? ? ? ctx.lineTo(Coordinates[i].X, Coordinates[i].Y);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? //先關閉繪制路徑。注意,此時將會使用直線連接當前端點和起始端點。
? ? ? ? ? ? ? ? ctx.closePath();
? ? ? ? ? ? ? ? ctx.lineWidth = 1;
? ? ? ? ? ? ? ? //最后,按照繪制路徑畫出直線
? ? ? ? ? ? ? ? ctx.stroke();
? ? ? ? ? ? }
? ? ? ? ? ? //初始化。
? ? ? ? ? ? windowLoadHandler();
? ? ? ? }
? ? ? ? var Debugger = function () { };
? ? ? ? Debugger.log = function (message) {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? console.log(message);
? ? ? ? ? ? }
? ? ? ? ? ? catch (exception) {
? ? ? ? ? ? ? ? return;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? //初始化入口
? ? ? ? function windowLoadHandler() {
? ? ? ? ? ? canvasApp();
? ? ? ? }
? ? ? ? //判斷瀏覽器對canvas是否支持
? ? ? ? function canvasSupport() {
? ? ? ? ? ? //return Modernizr.canvas;
? ? ? ? ? ? return true;
? ? ? ? }
? ? ? ? function canvasApp() {
? ? ? ? ? ? if (!canvasSupport()) {
? ? ? ? ? ? ? ? return;
? ? ? ? ? ? }
? ? ? ? ? ? canvas = document.getElementById("canvasOne");
? ? ? ? ? ? var context = canvas.getContext("2d");
? ? ? ? ? ? init();
? ? ? ? ? ? var shapes;
? ? ? ? ? ? var dragIndex;
? ? ? ? ? ? var dragging;
? ? ? ? ? ? var mouseX;
? ? ? ? ? ? var mouseY;
? ? ? ? ? ? var dragHoldX;
? ? ? ? ? ? var dragHoldY;
? ? ? ? ? ? function init() {
? ? ? ? ? ? ? ? shapes = Coordinates;
? ? ? ? ? ? ? ? drawScreen(Coordinates);
? ? ? ? ? ? ? ? canvas.addEventListener("mousedown", mouseDownListener, false);
? ? ? ? ? ? }
? ? ? ? ? ? function mouseDownListener(evt) {
? ? ? ? ? ? ? ? //如果是右鍵點擊,直接進入旋轉步驟
? ? ? ? ? ? ? ? if (evt.button == 2) { ChangeSwitcher(isOpenRotate); }
? ? ? ? ? ? ? ? //else if (evt.button == 1) { ChangeSwitcher(isOpenPan); }
? ? ? ? ? ? ? ? var highestIndex = -1;
? ? ? ? ? ? ? ? var bRect = canvas.getBoundingClientRect();
? ? ? ? ? ? ? ? mouseX = (evt.clientX - bRect.left) * (canvas.width / bRect.width);
? ? ? ? ? ? ? ? mouseY = (evt.clientY - bRect.top) * (canvas.height / bRect.height);
? ? ? ? ? ? ? ? //找到哪個是被選中的點
? ? ? ? ? ? ? ? switch (SwitchCase) {
? ? ? ? ? ? ? ? ? ? case isOpenPan:
? ? ? ? ? ? ? ? ? ? ? ? //find which shape was clicked
? ? ? ? ? ? ? ? ? ? ? ? for (var i = 0; i < Coordinates.length; i++) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (hitTest(Before_Coordinates[i], mouseX, mouseY)) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dragging = true;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (i > highestIndex) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //We will pay attention to the point on the object where the mouse is "holding" the object:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dragHoldX = mouseX - Before_Coordinates[i].X;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dragHoldY = mouseY - Before_Coordinates[i].Y;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? highestIndex = i;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dragIndex = i;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Point_FirstSelect = copyObject(Before_Coordinates[dragIndex]);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Point_FirstSelect_index = dragIndex;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? case isOpenRotate:
? ? ? ? ? ? ? ? ? ? ? ? //find which shape was clicked
? ? ? ? ? ? ? ? ? ? ? ? for (var i = 0; i < Coordinates.length; i++) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (hitTest(Before_Coordinates[i], mouseX, mouseY)) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dragging = true;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (i == Point_FirstSelect_index) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? alert("控制點選擇出現重復!");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (i > highestIndex) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //We will pay attention to the point on the object where the mouse is "holding" the object:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dragHoldX = mouseX - Before_Coordinates[i].X;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dragHoldY = mouseY - Before_Coordinates[i].Y;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? highestIndex = i;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dragIndex = i;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Point_FirstSelect = copyObject(Before_Coordinates[Point_FirstSelect_index]);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Point_SecondSelect = copyObject(Before_Coordinates[dragIndex]);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Point_SecondSelect_index = dragIndex;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? default: break;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if (dragging) { window.addEventListener("mousemove", mouseMoveListener, false);}
? ? ? ? ? ? ? ? canvas.removeEventListener("mousedown", mouseDownListener, false);
? ? ? ? ? ? ? ? window.addEventListener("mouseup", mouseUpListener, false);
? ? ? ? ? ? ? ? //code below prevents the mouse down from having an effect on the main browser window:
? ? ? ? ? ? ? ? if (evt.preventDefault) {
? ? ? ? ? ? ? ? ? ? evt.preventDefault();
? ? ? ? ? ? ? ? } //standard
? ? ? ? ? ? ? ? else if (evt.returnValue) {
? ? ? ? ? ? ? ? ? ? evt.returnValue = false;
? ? ? ? ? ? ? ? } //older IE
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? var isMouseUp = false;
? ? ? ? ? ? function mouseUpListener(evt) {
? ? ? ? ? ? ? ? if (!isMouseUp) {
? ? ? ? ? ? ? ? ? ? canvas.addEventListener("mousedown", mouseDownListener, false);
? ? ? ? ? ? ? ? ? ? window.removeEventListener("mouseup", mouseUpListener, false);
? ? ? ? ? ? ? ? ? ? if (dragging) {
? ? ? ? ? ? ? ? ? ? ? ? dragging = true;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? isMouseUp = true;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else {
? ? ? ? ? ? ? ? ? ? canvas.addEventListener("mousedown", mouseDownListener, false);
? ? ? ? ? ? ? ? ? ? window.removeEventListener("mouseup", mouseUpListener, false);
? ? ? ? ? ? ? ? ? ? if (dragging) {
? ? ? ? ? ? ? ? ? ? ? ? dragging = false;
? ? ? ? ? ? ? ? ? ? ? ? window.removeEventListener("mousemove", mouseMoveListener, false);
? ? ? ? ? ? ? ? ? ? ? ? Before_Coordinates = copyObject(After_Coordinates);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? isMouseUp = false;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? function mouseMoveListener(evt) {
? ? ? ? ? ? ? ? var posX;
? ? ? ? ? ? ? ? var posY;
? ? ? ? ? ? ? ? var shapeRad = shapes[dragIndex].rad;
? ? ? ? ? ? ? ? var minX = shapeRad;
? ? ? ? ? ? ? ? var maxX = canvas.width - shapeRad;
? ? ? ? ? ? ? ? var minY = shapeRad;
? ? ? ? ? ? ? ? var maxY = canvas.height - shapeRad;
? ? ? ? ? ? ? ? //getting mouse position correctly?
? ? ? ? ? ? ? ? var bRect = canvas.getBoundingClientRect();
? ? ? ? ? ? ? ? mouseX = (evt.clientX - bRect.left) * (canvas.width / bRect.width);
? ? ? ? ? ? ? ? mouseY = (evt.clientY - bRect.top) * (canvas.height / bRect.height);
? ? ? ? ? ? ? ? //clamp x and y positions to prevent object from dragging outside of canvas,dragHold是緩沖半徑
? ? ? ? ? ? ? ? posX = mouseX - dragHoldX;
? ? ? ? ? ? ? ? posX = (posX < minX) ? minX : ((posX > maxX) ? maxX : posX);
? ? ? ? ? ? ? ? posY = mouseY - dragHoldY;
? ? ? ? ? ? ? ? posY = (posY < minY) ? minY : ((posY > maxY) ? maxY : posY);
? ? ? ? ? ? ? ? //這里要重新計算坐標,可以根據這個值來計算坐標偏移量
? ? ? ? ? ? ? ? After_Coordinates[dragIndex].X = posX;
? ? ? ? ? ? ? ? After_Coordinates[dragIndex].Y = posY;
? ? ? ? ? ? ? ? var MousePoint = { X: posX, Y: posY };
? ? ? ? ? ? ? ? switch (SwitchCase)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? case isOpenPan:
? ? ? ? ? ? ? ? ? ? ? ? //所有坐標的平移差量
? ? ? ? ? ? ? ? ? ? ? ? var deltaX = After_Coordinates[dragIndex].X - Before_Coordinates[dragIndex].X;
? ? ? ? ? ? ? ? ? ? ? ? var deltaY = After_Coordinates[dragIndex].Y - Before_Coordinates[dragIndex].Y;
? ? ? ? ? ? ? ? ? ? ? ? showCos(deltaX, deltaY, MousePoint);
? ? ? ? ? ? ? ? ? ? ? ? moveOriginPic2Current(deltaX, deltaY);
? ? ? ? ? ? ? ? ? ? ? ? drawScreen(After_Coordinates);
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? case isOpenRotate:
? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? //計算夾角
? ? ? ? ? ? ? ? ? ? ? ? var jd1 = ComputeAngle(Point_FirstSelect, Point_SecondSelect);
? ? ? ? ? ? ? ? ? ? ? ? var jd2 = ComputeAngle(Point_FirstSelect, MousePoint);
? ? ? ? ? ? ? ? ? ? ? ? var jd_abs = Math.abs(jd1 - jd2);
? ? ? ? ? ? ? ? ? ? ? ? //順時針轉逆時針
? ? ? ? ? ? ? ? ? ? ? ? if (jd1 < jd2) thelta = (2 * Math.PI - jd_abs);
? ? ? ? ? ? ? ? ? ? ? ? else thelta = jd_abs;
? ? ? ? ? ? ? ? ? ? ? ? showCos2(thelta,MousePoint);
? ? ? ? ? ? ? ? ? ? ? ? rotateCoords(thelta, Point_FirstSelect, MousePoint);
? ? ? ? ? ? ? ? ? ? ? ? drawScreen(After_Coordinates);
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ? ? ? break; ;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? //對所有坐標進行平移
? ? ? ? ? ? function moveOriginPic2Current(deltX, deltY) {
? ? ? ? ? ? ? ? for (var i = 0; i < Coordinates.length; i++) {
? ? ? ? ? ? ? ? ? ? After_Coordinates[i].X = Before_Coordinates[i].X + deltX;
? ? ? ? ? ? ? ? ? ? After_Coordinates[i].Y = Before_Coordinates[i].Y + deltY;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? //對所有坐標進行旋轉變換,FPoint為所選擇的第一個點,angle記錄為與逆時針旋轉角度,mousePoint是當前鼠標點
? ? ? ? ? ? function rotateCoords(angle, FPoint, mousePoint) {
? ? ? ? ? ? ? ? for (var i = 0; i < Coordinates.length; i++) {
? ? ? ? ? ? ? ? ? ? if (i != Point_FirstSelect_index) {
? ? ? ? ? ? ? ? ? ? ? ? //canvas的坐標軸是發生轉變的
? ? ? ? ? ? ? ? ? ? ? ? var x0 = (Before_Coordinates[i].X - FPoint.X) * Math.cos(angle) - (FPoint.Y - Before_Coordinates[i].Y) * Math.sin(angle) + FPoint.X;
? ? ? ? ? ? ? ? ? ? ? ? var y0 = (Before_Coordinates[i].X - FPoint.X) * Math.sin(angle) + (FPoint.Y - Before_Coordinates[i].Y) * Math.cos(angle) - FPoint.Y;
? ? ? ? ? ? ? ? ? ? ? ? After_Coordinates[i].X = x0;
? ? ? ? ? ? ? ? ? ? ? ? After_Coordinates[i].Y = -y0; //y=-y
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? //判斷點擊的位置是否為拾取點
? ? ? ? ? ? function hitTest(shape, mx, my) {
? ? ? ? ? ? ? ? var dx = mx - shape.X;
? ? ? ? ? ? ? ? var dy = my - shape.Y;
? ? ? ? ? ? ? ? var d = document.getElementById('BufferRange').value;
? ? ? ? ? ? ? ? return ((dx * dx + dy * dy) < (d * d)); //所選的緩沖半徑為4
? ? ? ? ? ? }
? ? ? ? ? ? //根據坐標數組在canvas上畫圖(全部為直線)
? ? ? ? ? ? function drawShapes(Coords) {
? ? ? ? ? ? ? ? context.beginPath();
? ? ? ? ? ? ? ? context.strokeStyle = "blue";
? ? ? ? ? ? ? ? //設置路徑起點坐標
? ? ? ? ? ? ? ? context.moveTo(Coords[0].X, Coords[0].Y);
? ? ? ? ? ? ? ? for (var i = 1; i < Coordinates.length; i++) {
? ? ? ? ? ? ? ? ? ? context.lineTo(Coords[i].X, Coords[i].Y);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? //先關閉繪制路徑。注意,此時將會使用直線連接當前端點和起始端點。
? ? ? ? ? ? ? ? context.lineWidth = 2;
? ? ? ? ? ? ? ? //最后,按照繪制路徑畫出直線
? ? ? ? ? ? ? ? context.closePath();
? ? ? ? ? ? ? ? context.stroke();
? ? ? ? ? ? }
? ? ? ? ? ? //畫圖的屏幕處理
? ? ? ? ? ? function drawScreen(coords) {
? ? ? ? ? ? ? ? context.clearRect(0, 0, canvas.width, canvas.height);
? ? ? ? ? ? ? ? drawShapes(coords);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? //顯示備準的結果
? ? ? ? function showResult(cos) {
? ? ? ? ? ? var s = "";
? ? ? ? ? ? s += "<From x,y> <space> <To x,y> \r\n"
? ? ? ? ? ? for (var i = 0; i < Coordinates.length; i++) {
? ? ? ? ? ? ? ? //cos[i] = Mercator2lonLat(cos[i]);
? ? ? ? ? ? ? ? s += Coordinates[i].X + "," + Coordinates[i].Y + " " + cos[i].lon + "," + cos[i].lat + "\r\n";
? ? ? ? ? ? }
? ? ? ? ? ? document.getElementById('Result').value = s;
? ? ? ? }
///地圖操作
? ? ? ? var map, layer;
? ? ? ? //var url = "http://101.251.247.242:8090/iserver/services/map-jingjin/rest/maps/京津地區地圖";
? ? ? ? //var Center_LonLat =new SuperMap.LonLat(117.01, 40.04);
? ? ? ? var url = "http://101.251.247.242:8090/iserver/services/map-changchun/rest/maps/長春市區圖";
? ? ? ? var Center_LonLat =new SuperMap.LonLat(5105, -3375);
? ? ? ? var vectorLayer;
? ? ? ? var FeatureStyle = {
? ? ? ? ? ? strokeColor: "#304DBE",
? ? ? ? ? ? strokeWidth: 2,
? ? ? ? ? ? pointerEvents: "visiblePainted",
? ? ? ? ? ? fillColor: "#304DBE",
? ? ? ? ? ? fillOpacity: 0.8
? ? ? ? };
? ? ? ? function init() {
? ? ? ? ? ? map = new SuperMap.Map("map", { controls: [
? ? ? ? ? ? new SuperMap.Control.Navigation(),
? ? ? ? ? ? new SuperMap.Control.Zoom(),
? ? ? ? ? ? new SuperMap.Control.MousePosition()]
? ? ? ? ? ? });
? ? ? ? ? ? layer = new SuperMap.Layer.TiledDynamicRESTLayer("China", url, null, { maxResolution: "auto" });
? ? ? ? ? ? layer.events.on({ "layerInitialized": addLayer });
? ? ? ? ? ? //添加圖層
? ? ? ? ? ? vectorLayer = new SuperMap.Layer.Vector("Vector Layer", { renderers: ["Canvas2"] });
? ? ? ? ? ? map.addLayer(vectorLayer);
? ? ? ? ? ? //地圖上移動鼠標時顯示坐標
? ? ? ? ? ? map.events.on({
? ? ? ? ? ? ? ? "mousemove": function (e) {
? ? ? ? ? ? ? ? ? ? var Position = e.xy.clone();
? ? ? ? ? ? ? ? ? ? var pixcel = new SuperMap.Pixel(e.layerX, e.layerY);
? ? ? ? ? ? ? ? ? ? var currPoint = map.getLonLatFromPixel(pixcel);
? ? ? ? ? ? ? ? ? ? document.getElementById('Coords_pic').value = ?currPoint.lon + "," + currPoint.lat;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? });
? ? ? ? }
? ? ? ? //初始化完成后添加圖層
? ? ? ? function addLayer() {
? ? ? ? ? ? map.addLayer(layer);
? ? ? ? ? ? map.setCenter(Center_LonLat, 0);
? ? ? ? }
? ? ? ? //調整canvas、pic的層次關系,控制canvas在上面一層
? ? ? ? function ShowCanvas() {
? ? ? ? ? ? document.getElementById('canvasOne').style.zIndex = 2;
? ? ? ? ? ? document.getElementById('map').style.zIndex = 1;
? ? ? ? }
? ? ? ? //調整canvas、pic的層次關系,控制地圖在上面一層
? ? ? ? function ShowMap() {
? ? ? ? ? ? document.getElementById('canvasOne').style.zIndex = 1;
? ? ? ? ? ? document.getElementById('map').style.zIndex = 2;
? ? ? ? }
? ? ? ? //執行按鈕,將要素繪制到地圖的矢量圖層上
? ? ? ? function Work() {
? ? ? ? ? ? //將pixel點數組 轉為 地理坐標組
? ? ? ? ? ? var SuperCoordnates = getSuperMapCoords();
? ? ? ? ? ? var SuperGeometries = getSuperMapGeometries(SuperCoordnates);
? ? ? ? ? ? var linearRings = new SuperMap.Geometry.LinearRing(SuperGeometries);
? ? ? ? ? ? var Polygon = new SuperMap.Geometry.Polygon([linearRings]);
? ? ? ? ? ? var PolygonFeature = new SuperMap.Feature.Vector(Polygon);
? ? ? ? ? ? PolygonFeature.style = FeatureStyle;
? ? ? ? ? ? //添加要素
? ? ? ? ? ? vectorLayer.addFeatures([PolygonFeature]);
? ? ? ? ? ? showResult(SuperCoordnates);
? ? ? ? }
? ? ? ? //由超圖經緯度坐標串生成超圖點對象數組
? ? ? ? function getSuperMapGeometries(s) {
? ? ? ? ? ? var points = [];
? ? ? ? ? ? for (var i = 0; i < Coordinates.length; i++) {
? ? ? ? ? ? ? ? points.push(new SuperMap.Geometry.Point(s[i].lon, s[i].lat));
? ? ? ? ? ? }
? ? ? ? ? ? return points;
? ? ? ? }
? ? ? ? //由屏幕坐標串轉為超圖經緯度坐標串
? ? ? ? function getSuperMapCoords() {
? ? ? ? ? ? var s = [];
? ? ? ? ? ? for (var i = 0; i < Coordinates.length; i++) {
? ? ? ? ? ? ? ? var lonlat = map.getLonLatFromPixel(new SuperMap.Pixel(After_Coordinates[i].X, After_Coordinates[i].Y));
? ? ? ? ? ? ? ? s.push(lonlat);
? ? ? ? ? ? }
? ? ? ? ? ? return s;
? ? ? ? }
? ? ? ? //改變操作狀態
? ? ? ? function ChangeSwitcher(SWCase) {
? ? ? ? ? ? switch (SWCase) {
? ? ? ? ? ? ? ? case 1:
? ? ? ? ? ? ? ? ? ? SwitchCase = 1;
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case 2:
? ? ? ? ? ? ? ? ? ? SwitchCase = 2;
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? ? ? Before_Coordinates = copyObject(After_Coordinates);
? ? ? ? }
? ? ? ? //對象深拷貝的一種方法
? ? ? ? function copyObject(source) {
? ? ? ? ? ? var result = {};
? ? ? ? ? ? for (var key in source) {
? ? ? ? ? ? ? ? result[key] = typeof source[key] === 'object' ? copyObject(source[key]) : source[key];
? ? ? ? ? ? }
? ? ? ? ? ? return result;
? ? ? ? }
? ? ? ??
//這一塊都用于測試
? ? ? ? //在平移的時候展示中間參數
? ? ? ? function showCos(dx,dy,MouseP) {
? ? ? ? ? ? var s = "";
? ? ? ? ? ? s += "鼠標位置(pixel):\r\nX:" + MouseP.X + " Y:" + MouseP.Y + "\r\n";
? ? ? ? ? ? s += "拖拽點編號:" + Point_FirstSelect_index + "\r\n";
? ? ? ? ? ? s += "旋轉中心點\r\n:X-" + Point_FirstSelect.X + "Y-" + Point_FirstSelect.Y + "\r\n";
? ? ? ? ? ? s += "平移量: X-"+dx +" Y-"+dy+ "\r\n";
? ? ? ? ? ? document.getElementById("showCoords").value = s;
? ? ? ? }
? ? ? ? //在旋轉的時候展示中間參數
? ? ? ? function showCos2(angle,MouseP) {
? ? ? ? ? ? var s = "";
? ? ? ? ? ? s += "逆時針旋轉角:" + 180/Math.PI*angle + "度\r\n";
? ? ? ? ? ? s += "鼠標位置(pixel)X:" + MouseP.X + " " + "鼠標Y:" + MouseP.Y+"\r\n";
? ? ? ? ? ? s += "旋轉中心點坐標:\r\nX-" + Point_FirstSelect.X + " Y-" + Point_FirstSelect.Y + "\r\n";
? ? ? ? ? ? s += "定位方向點坐標:\r\nX-" + Point_SecondSelect.X + " Y-" + Point_SecondSelect.Y + "\r\n";
? ? ? ? ? ? document.getElementById("showCoords").value = s;
? ? ? ? }
? ? ? ? //測試用的方法
? ? ? ? function getSomeTestInfo() {
? ? ? ? ? ? alert("Canvas的index:" + document.getElementById('Pic').style.zIndex);
? ? ? ? ? ? alert("map的index:" + document.getElementById('map').style.zIndex);
? ? ? ? ? ? displayProp("Pic的Style屬性:" + document.getElementById('Pic').style);
? ? ? ? }
? ? ? ? //獲取js對象所有屬性(這個方法用于測試)
? ? ? ? function displayProp(obj) {
? ? ? ? ? ? var names = "";
? ? ? ? ? ? for (var name in obj) {
? ? ? ? ? ? ? ? names += name + ": " + obj[name] + ", \r\n";
? ? ? ? ? ? }
? ? ? ? ? ? alert(names);
? ? ? ? }
? ? ? ? //使用滑輪直接進入地圖
? ? ? ? function Wheel2Map(e) {
? ? ? ? ? ? document.getElementById('canvasOne').style.zIndex = 1;
? ? ? ? ? ? document.getElementById('map').style.zIndex = 2;
? ? ? ? }
? ? ? ? //判斷緩沖范圍必須為正數
? ? ? ? function valueIsPositive() {
? ? ? ? ? ? if (document.getElementById('BufferRange').value <= 0) {
? ? ? ? ? ? ? ? alert("緩沖范圍請填寫正值");
? ? ? ? ? ? ? ? document.getElementById('BufferRange').value = 10;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? function Reset() {
? ? ? ? ? ? var ctx = canvas.getContext("2d");
? ? ? ? ? ? ctx.clearRect(0, 0, 1000, 1000);
? ? ? ? ? ? vectorLayer.removeAllFeatures();
? ? ? ? ? ? drawJson();
? ? ? ? ? ? SwitchCase = isOpenPan;
? ? ? ? }
? ? </script>
</head>
<body οnlοad="init()" onmousewheel="Wheel2Map(event)";>
? ? ? ? <div id="map"></div>
? ? ? ? <canvas id="canvasOne" width="1000px" height="1000px"></canvas>
? ? ? ? <div id="rightdiv">
? ? ? ? ? ? ? ? <div id="FirstFloorDiv">
? ? ? ? ? ? ? ? ? ? <input type="button" value="顯示建筑" οnclick="ShowCanvas()" />
? ? ? ? ? ? ? ? ? ? <input type="button" value="顯示地圖" οnclick="ShowMap()" />
? ? ? ? ? ? ? ? ? ?  ?
? ? ? ? ? ? ? ? ? ? <input type="button" value="進行平移" οnclick="ChangeSwitcher(1)" />
? ? ? ? ? ? ? ? ? ? <input type="button" value="進行旋轉" οnclick="ChangeSwitcher(2)" />
? ? ? ? ? ? ? ? ? ?  ?
? ? ? ? ? ? ? ? ? ? <input type="button" value="重啟" οnclick="Reset()" />
? ? ? ? ? ? ? ? ? ? </br></br>地圖數據源:
? ? ? ? ? ? ? ? ? ? <select id="DataSource" name="DataSource" autofocus="true">
? ? ? ? ? ? ? ? ? ? ? ? <option value="超圖長春">超圖長春</option>
? ? ? ? ? ? ? ? ? ? ? ? <option value="超圖數據服務">超圖數據服務</option>
? ? ? ? ? ? ? ? ? ? ? ? <option value="WMS服務">WMS服務</option>
? ? ? ? ? ? ? ? ? ? </select>
? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? <div id="SecondFloorDiv">
? ? ? ? ? ? ? ? ? ? <div id="top_CalibrationDiv">
? ? ? ? ? ? ? ? ? ? ? ? 請在下方輸入框中粘貼Json格式字符串:</br>
? ? ? ? ? ? ? ? ? ? ? ? <textarea id="Jsontxt"></textarea>
? ? ? ? ? ? ? ? ? ? ? ? <input id="Calibration" type="button" style="left:120px" value="配準" οnclick="drawJson()" />
? ? ? ? ? ? ? ? ? ? ? ? <input id="Go" type="button" value="執行" οnclick="Work()" />
? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? ? ? <div id="PicBox">
? ? ? ? ? ? ? ? ? ? ? ? 點拾取的緩沖范圍(pixel):<input type="text" id="BufferRange" style="width: 30px" value="10" οnblur="valueIsPositive()"/></br>
? ? ? ? ? ? ? ? ? ? ? ? 地圖坐標:<input type="text" id="Coords_pic" style="width: 98%" />
? ? ? ? ? ? ? ? ? ? ? ? </br>當前參數:</br>
? ? ? ? ? ? ? ? ? ? ? ? ?<textarea id="showCoords" style="height: 320px; width:98%"></textarea>
? ? ? ? ? ? ? ? ? ? ? ? ?</br>輸出結果:</br>
? ? ? ? ? ? ? ? ? ? ? ? ?<textarea id="Result" style="height: 450px; width:98%"></textarea>
? ? ? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? </div>
? ? ? ? </div>
</body>
</html>
<script type="text/javascript">
? ? //一些瑣碎的處理
? ? //禁用Canvas的右鍵菜單
? ? document.getElementById('canvasOne').oncontextmenu = function () {
? ? ? ? return false;
? ? } ?
</script>
總結
以上是生活随笔為你收集整理的在canvas上进行绘图,实现要素配准的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 推荐一款优秀的通用管理后台
- 下一篇: 计算机系统基础实验-LinkLab实验