I downloaded some tiles from ArcGIS.Imagery with SAS Planet
The tiles is in folders like
ArcGIS.Imagery/z2/0/x1/0/y2.jpg
And I use this TileLayer to display it on leaflet.
L.TileLayer.customTiles = L.TileLayer.extend({
getTileUrl: function (t) {
console.log('coords', t);
z = t.z,
x = t.x,
y = t.y,
z0 = t.z,
x0 = Math.floor(t.x / 1024),
x1 = Math.floor(t.x % 1024),
y0 = Math.floor(t.y / 1024),
y1 = Math.floor(t.y % 1024)
const d = `ArcGIS.Imagery/z${z0}/${x0}/x${x1}/${y0}/y${y1}.jpg`;
console.log('d', d);
return d;
}
});
L.tileLayer.customTiles = function () {
return new L.TileLayer.customTiles();
}
L.tileLayer.customTiles().addTo(map);
But it looks like there is wrong coordinates. Here is what I got as a result. Any ideas how to fix it? Thanks
Related
I am trying to follow this example from Matlab about coloring scatter points as a rainbow, while the x-position of the points is progressing towards the right side.
Here under "Vary Circle Color":
https://de.mathworks.com/help/matlab/ref/scatter.html
x = linspace(0,3*pi,200);
y = cos(x) + rand(1,200);
c = linspace(1,10,length(x));
scatter(x,y,[],c)
While c as a variable goes from 1 to 20 with 200 interpolations. I am trying to replicate this for my piece of code, but I keep getting random color and the x-axis isn't matching the rainbow distribution as this:
g = 6;
pt_x = [0, g, -g];
pt_y = [g, -g, -g];
sz = 10;
loop = 100;
% var(1, loop) = 0;
% c = linspace(-10,10,length(var));
% c = 1:loop;
c = -loop/2:1:loop/2 -1;
rand_x = randi([-g,g],1,1);
rand_y = randi([-g,g],1,1);
for i = 1:loop
r = randi([1,3],1,1);
x1 = (rand_x + pt_x(r)) / 2;
y1 = (rand_y + pt_y(r)) / 2;
seq_x(1, i) = x1;
seq_y(1, i) = y1;
rand_x = x1;
rand_y = y1;
end
scatter(seq_x, cos(seq_x),[],c, 'filled');
What am I missing here exactly? I would appreciate any help!
Expected to get a rainbow pattern
It resulted in a random pattern
I have 4 points of football pitch (corner points):
P1(lat, lon, alt), P2(lat, lon, alt), P3(lat, lon, alt), P4(lat, lon, alt).
and a location on the pitch:
L(lat, lon, alt)
I want to convert L(lat, lon, alt) to L(x, y) on a rectangle with size of (W, H).
How to implement this conversion function? (I preferred C# language but implementation language is not important)
The following image describes my problem (I don't know how to implement the Function box):
First off, because output coordinates are 2D, I'm going to assume that we can get rid of altitude information from input coordinates. So input data consist of four points defining the input rectangle:
P1(lat, lon), P2(lat, lon), P3(lat, lon), P4(lat, lon)
and dimensions of the output rectangle: w, h.
I'm also going to ignore the curvature of the Earth (football pitch is small enough). With those assumptions we can implement the conversion function, by performing affine transformation. It would be wasteful to create transformation matrix each time we want to perform a transformation. For that reason we need two functions: first one to create the transformation matrix (called only once), and the second one that will use that matrix to perform transformation itself (called possibly many times, one time for each point we want to transform), something like:
tm = createTransformationMatrix(P1, P2, P4, w, h)
inPoint = (200, 50)
outPoint = transform(inPoint, tm)
Note that we only need three of four input points to unambiguously define a rotated rectangle in 2D euclidean space.
Here is the implementation of createTransformationMatrix and transform functions:
const run = function() {
// Creates transformation matrix to transform
// from rectangle somewhere in 2D space with coordinates p0, px, pi, py
// to rectangle with coordinates (x=0, y=0), (x=w, y=0), (x=w, y=h), (x=0, y=h).
// Note that: p0 is mapped to (x=0, y=0)
// px is mapped to (x=w, y=0)
// py is mapped to (x=0, y=h)
const createTransformationMatrix = function(p0, px, py, w, h) {
// Translate px and py by p0 - pxt and pyt are px and py vectors in coordinate system in which p0 is at the origin
const pxt = {
x: px.x - p0.x,
y: px.y - p0.y,
};
const pyt = {
x: py.x - p0.x,
y: py.y - p0.y,
};
// Create transformation matrix, which is inverse of transformation matrix that:
// 1. Transforms (x=0, y=0) to (x=p0.x, y=p0.y)
// 2. Transforms (x=1, y=0) to (x=p0.x + pxt.x / w, y=p0.y + pxt.y / w)
// 3. Transforms (x=0, y=1) to (x=p0.x + pyt.x / h, y=p0.y + pyt.y / h)
return Matrix.invert3([
[pxt.x / w, pyt.x / h, p0.x],
[pxt.y / w, pyt.y / h, p0.y],
[0 , 0 , 1 ],
]);
};
const transform = function(point, transformationMatrix) {
// Convert point to homogeneous coordinates
const inputVector = [
[point.x],
[point.y],
[1],
];
// Transform inputVector
const outputVector = Matrix.multiply(transformationMatrix, inputVector);
// Convert outputVector back to cartesian coordinates and return
return {
x: outputVector[0][0] / outputVector[2][0],
y: outputVector[1][0] / outputVector[2][0],
};
};
const w = 220;
const h = 115;
const p1 = {x:-79, y:80 };
const p2 = {x:9, y:-96};
const p3 = {x:55, y:-72};
const p4 = {x:-34, y:105};
const tm = createTransformationMatrix(p1, p2, p4, w, h);
const inPoint = {x: 200, y: 50};
const outPoint = transform(inPoint, tm);
console.log(`(${inPoint.x}, ${inPoint.y}) --[transform]--> (${outPoint.x}, ${outPoint.y})`);
}
//// Matrix ////
const Matrix = {};
Matrix.scale = (s, m) => m.map(x => Array.isArray(x) ? Matrix.scale(s, x) : s * x);
Matrix.multiply = function(a, b) {
const aNumRows = a.length, aNumCols = a[0].length;
const bNumRows = b.length, bNumCols = b[0].length;
const m = new Array(aNumRows);
for (let r = 0; r < aNumRows; ++r) {
m[r] = new Array(bNumCols);
for (let c = 0; c < bNumCols; ++c) {
m[r][c] = 0;
for (let i = 0; i < aNumCols; ++i)
m[r][c] += a[r][i] * b[i][c];
}
}
return m;
};
Matrix.invert3 = function(m) {
const [[a, b, c],
[d, e, f],
[g, h, i]] = m;
const det = a*(e*i - f*h) - b*(d*i - f*g) + c*(d*h - e*g);
return Matrix.scale(1/det, [
[e*i - f*h, c*h - b*i, b*f - c*e],
[f*g - d*i, a*i - c*g, c*d - a*f],
[d*h - e*g, b*g - a*h, a*e - b*d],
]);
};
//////////////
run();
I've included all the matrix processing logic, so that this code snippet is self contained, but I would suggest you to instead use some linear algebra library for matrix processing.
I've also made a more visual demo.
I am using contourf function with binary image. I am trouble how i can get the area and centroid of the different surface in the image, need this task to classify the objects.
You need to use the the Contour Matrix output
Here is an example:
function data = ContourInfo(C)
data = [];
if isempty(C)
return
end
k = 1;
j = 1;
while j < size(C,2);
data(k).numxy = C(2,j);
data(k).x = C(1,j+1:j+data(k).numxy);
data(k).y = C(2,j+1:j+data(k).numxy);
data(k).level = C(1,j);
[data(k).centroid(1) data(k).centroid(2) data(k).area] = ...
polycentroid(data(k).x, data(k).y);
data(k).area = polyarea(data(k).x, data(k).y);
data(k).centroid = polycentroid(data(k).x, data(k).y);
j = j + data(k).numxy + 1;
k = k+1;
end
function [x0,y0,a] = polycentroid(x,y)
[m1,n1] = size(x); [m2,n2] = size(y);
n = max(m1,n1);
x = x(:); y = y(:);
x2 = [x(2:n);x(1)];
y2 = [y(2:n);y(1)];
a = 1/2*sum (x.*y2-x2.*y);
x0 = 1/6*sum((x.*y2-x2.*y).*(x+x2))/a;
y0 = 1/6*sum((x.*y2-x2.*y).*(y+y2))/a;
Call as follow:
Z = peaks(20);
[C, h] = contourf(Z,10);
contourData = ContourInfo(C)
disp('Area of contour 1:');
disp(contourData(1).area
disp('Centroid of contour 1:');
disp(contourData(1).centroid);
I have to draw a hipsometric map on a 3D plot. I have two vectors 1x401 (named xLabels and yLabels) which are the geo coordinates, and401x401(namedA`) matrix with the altitude data. To plot the data I use:
surf(xLabels, yLabels,A,'EdgeColor','None','Marker','.');
which leads to something like that:
But i would like to have something like that:
On the second image, only the surface is plotted, while my image looks like pillars.
I tried even make my vectors to 401x401 using meshgrid but it did not have any effect.
Do you have any idea what I should change?
#EDIT
I checked for X and Y data. I quess is too small interval (0.0083), but when i try plot good second of upper plots with same interval it draws correctly.
#EDIT2:
sizeX = 4800;
sizeY = 6000;
pixdegree = 0.0083; % 1 pixel is 0.0083 degree on map
intSize = 2;
lon = 37 + (35/60);
lat = 55+ (45/60);
fDEM = 'E020N90';
fHDR = 'E020N90.HDR';
[startXY, endXY] = calcFirstPixel(lon, lat); %calc borders for my area
f = fopen('E020N90.DEM');
offset = (startXY(1,2)*sizeX*intSize)+(startXY(1,1)*intSize);
fseek(f, offset,0); %seek from curr file pos
x = 0;
A = [];
BB = [];
jump = (intSize*sizeX)-(401*2);
while x<401
row = fread(f, 802);
fseek(f, jump, 0); %jump 2 next row
A = [A row];
x = x+1;
end
fclose(f);
A = A';
A = A(:,2:2:802);
m1 = min(A(:)); %wartość minimalna dla naszej podziałki
m2 = max(A(:)); %wartość maksymalna dla naszej podziałki
step = m2/8; % będzie 8 kolorów
highScale = m1:step:m2-step; %wartości graniczne dla każdego z nich
%handles.axes1 = A;
colormap(hObject, jet(8));
startXtick = 20 + pixdegree*startXY(1,1);
endXtick = 20 + pixdegree*endXY(1,1);
startYtick = 90 - pixdegree*endXY(1,2);
endYtick = 90 - pixdegree*startXY(1,2);
[XX,YY] = ndgrid(startXtick:pixdegree:endXtick,startYtick:pixdegree:endYtick);
xLabels = startXtick:pixdegree:endXtick;
yLabels = startYtick:pixdegree:endYtick;
surf(xLabels, yLabels,A,'EdgeColor','None','Marker','.');
set(gca,'YDir','normal');
grid on;
view([45 45])
And .DEM files
function [startXY, endXY] = calcFirstPixel(lon,lat)
global fHDR;
format = '%s %s';
f = fopen(fHDR);
cont = textscan(f, format);
LonStart = str2double(cont{1,2}{11,1});
LatStart = str2double(cont{1,2}{12,1});
diffPerPix = str2double(cont{1,2}{13,1});
fclose(f);
x = LonStart;
countX = 0
y = LatStart;
countY= 0;
while x<lon
x=x+diffPerPix
countX = countX +1;
end
while y>lat
y=y-diffPerPix
countY = countY+1;
end
startXY= [countX-200 countY-200];
endXY = [countX+200 countY+200];
end
For my project, I have a lot of pictures that I need to extract a ROI. When my project starts, I want a picture to show and then the user to select the ROI that he/she wants. The function imrect seems to be doing that. I am trying to get the coordinate of the rectangle, once it has been dragged or resized. The problem is that the values returned do not seem to be correct.
I can't seem to find the problem and the related questions didn't help. I tried using imcrop, but couldn't do any better...
function [ new_image ] = getRoi(image)
rect = size(image);
rect = round(rect ./2);
figure, imshow(image);
h = imrect(gca, [5 5 rect(2) rect(1)]);
addNewPositionCallback(h,#(p) title(mat2str(p,3)));
fcn = makeConstrainToRectFcn('imrect',get(gca,'XLim'),get(gca,'YLim'));
accepted_pos = wait(h);
setPositionConstraintFcn(h,fcn);
%getPositionConstraintFcn(h);
pos = getPosition(h);
if round(pos(1)) < round(pos(2))
X1 = round(pos(1))
X2 = round(pos(2))
else
X1 = round(pos(2))
X2 = round(pos(1))
end
if round(pos(3)) < round(pos(4))
Y1 = round(pos(3))
Y2 = round(pos(4))
else
Y1 = round(pos(4))
Y2 = round(pos(3))
end
new_image = image(Y1:Y2, X1:X2);
%name = strcat('Roi_', datestr(clock, 'yyyymmddTHHMMSS'),'.png');
%prtIm(new_image, name, '-s');
new_image = image;
end
getPosition returns [xmin, ymin, width, height]. To get the coordinates you want, try
X1 = round(pos(1));
Y1 = round(pos(2));
X2 = round(X1 + pos(3));
Y2 = round(Y1 + pos(4));