Convert “world file” GIS for MapBox GL? - gis

I'm trying to display GIF image with a world file (http://webhelp.esri.com/arcims/9.2/general/topics/author_world_files.htm) on Mapbox gl. The image is displayed but it looks like it was shifted couple of degrees up. The following are the setups I followed to calculate the coordinates
A:0.017971305190311 <- Horizontal Pixel Distribution (deg/width) (A)
D:0.000000000000000 <- X Rotation (D)
B:0.000000000000000 <- Y Rotation (B)
E:-0.017971305190311 <- Vertical Pixel Distribution (deg/height) (E)
C:-127.620375523875420 <- X Coordinate for the center of the top left pixel (C)
F:50.406626367301044 <- Y Coordinate for the center of the top left pixel (F)
Used the following equation to calculate the Lat/Long # each corner
Xn = Ax + By + C
Yn = Dx + Ey + F
[-127.62037552387542,50.406626367301044],
[-66.51793787681802,50.406626367301044],
[-66.51793787681802,21.652538062803444],
[-127.62037552387542,21.652538062803444]
The Image documentation state that it was created using standard geographic projection referenced to North American Datum 1983 (NAD83). Is there any other steps needed to be done to display the image correctly on the map ?
Thanks

Related

Maps into Forge Viewer

Trying to follow the steps https://forge.autodesk.com/blog/add-mapbox-google-maps-forge-viewer but i can't place the model correctly on the map.
I am running the functions listed here: https://learn.microsoft.com/en-us/bingmaps/articles/bing-maps-tile-system:
LatLongToPixelXY(latitude, longitude, 7, out pixelX, out pixelY);
PixelXYToTileXY(pixelX, pixelY, out tileX, out tileY);
The result pixelX = 16225, pixelY = 12249, tileX = 63, tileY = 47.
I substitute the previous values:
map.position.set(16225,12249,-45);
class MapPlaneNode extends MapNode {
constructor(parentNode = null, mapView = null, location = MapNode.ROOT, level = 7, x = 63, y = 47)
The result is that the model comes out small and not positioned correctly. In the image, the red arrow is where the model is inserted, and the green arrow is where it should be.
image of result
What am I doing wrong?
Thank you very much
Positioning the model is a little tricky.
In the demo I created, I originally used world coordinates, where I set the root tile as level 0, and used the correct lat/long coordinate utils function to position the revit model in the correct location.
Unfortunately, the precision caused a rendering problem with the post-renderer (line edges were missing, and some strange z-fighting precision issues)...
so, I decided to hack the level, and move the map into the position I wanted and center the revit model at origin 0,0,0.
This made things a lot more manual and rather tricky, but it got around the rendering issue and also limited the user into a small area in the world, which I preferred.
I suggest changing the root tile back to zero, and adjusting the model position globaloffset to the value of the lat/long W84 utils. See the blog post and also the coordinates section of the geo-three repo, for more details here: https://github.com/tentone/geo-three#coordinates
Found a trick to adjust the map. It is still manual but it's fairly quick:
Calculate Tile X and Y (you did that step already, it's just for reference):
Copy the TileSystem class from the the link bing-maps-tile-system you posted into https://dotnetfiddle.net/
(you'll also need to add: using System.Text)
Change the main as follows
public static void Main()
{
int pixelX, pixelY, tileX, tileY;
TileSystem.LatLongToPixelXY(YOUR LAT HERE, YOUR LONG HERE, 7, out pixelX, out pixelY);
Console.WriteLine("LatLongToPixelXY: " + pixelX.ToString() + ", " + pixelY.ToString());
TileSystem.PixelXYToTileXY(pixelX, pixelY, out tileX, out tileY);
Console.WriteLine("PixelXYToTileXY: " + tileX.ToString() + ", " + tileY.ToString());
}
This will give you the TileX and Tile Y that you'll need to replace in the Extension.
Calculate Position
In the Extension set the X, Y position to 0,0, and the adjust the Z so that the map is below your model
map.position.set(0, 0, z);
Run the Extension and see where your project lands on the map. Now locate this landing point in Google maps (I found it useful at this stage to search the map using a corner between two streets by entering for example: Parker St & Wilson Rd). When you've found it, click on the landing point in Google map to place a Marker, then right-click on the marker and select Measure Distance. You will have to measure the distance to your destination both vertically, and horizontally (not directly to it). For example you'll get dH = 43.5km and dV = 17.8km
And this is were the magic happens: Multiply both numbers by 3400 if your distance is in km (or by 2113 if you distance is in miles) and set the position with those values:
dH * 3400 = 147900
dV * 3400 = 60520
If your destination is to the E or S use positive values.
If your destination is to the W or N use negative values
map.position.set(147900, -60520, z);
Now it won't be perfect, but it'll be close enough to finish adjusting the value manually.

How can I adjust the distance in a bipartite pie graph using igraph?

I am using igraph (R) to draw a bipartite graph with pie shaped vertices.
Simple example:
library(igraph)
inc <- matrix(sample(0:1, 50, replace = TRUE, prob=c(2,1)), 10, 5)
values <- lapply(1:15, function(x) sample(1:10,3))
g <- graph_from_incidence_matrix(inc)
plot(g, vertex.shape="pie", vertex.pie=values,
vertex.pie.color=list(heat.colors(5)),
layout = layout_as_bipartite)
tall graph
I would like to decrease the distance between the upper and lower nodes. If I use asp I get the following
plot(g, vertex.shape="pie", vertex.pie=values,
vertex.pie.color=list(heat.colors(5)),
layout = layout_as_bipartite, asp = 0.3)
graph with adjusted aspect ratio
The nodes are not round anymore. This doesn't happen when the vertices are not pie.
How can I adjust the distance without skewing the pie shapes?
Many thanks!

Explanation of a Hough accumulator that does not match image

I was having fun with image processing and hough transforms on Octave but the results are not the expected ones.
Here is my edges image:
and here is my hough accumulator (x-axis is angle in deg, y-axis is radius):
I feel like I am missing the horizontal streaks but there is no local maximum in the accumulator for the 0/180 angle values.
Also, for the vertical streaks, the value of the radius should be equal to the x value of the edge's image, but instead the values of r are very high:
exp: the first vertical line on the left of the image has an equation of x=20(approx) -> r.r = x.x + y.y -> r=x -> r=20
The overall resulting lines detected do not match the edges at all:
Acculmulator with detected maxima:
Resulting lines:
As you can see the maximas of the accumulator are satisfyingly detected but the resulting lines' radius values are too high and theta values are missing.
It almost looks like the hough transform accumulator does not correspond to the image...
Can someone help me figure out why and how to correct it?
Here is my code:
function [r, theta] = findScratches (img, edge)
hough = houghtf(edge,"line", pi*[0:360]/180);
threshHough = hough>.5*max(hough(:));
[r, theta] = find(threshHough>0);
%deg to rad for the trig functions
theta = theta/180*pi;
%according to octave doc r range is 2*diagonal
%-> bring it down to 1*diagonal or all lines are out of the picture
r = r/2;
%coefficients of the line y=ax+b
a = -cos(theta)./sin(theta);
b = r./sin(theta);
x = 1:size(img,2);
y = a * x + b;
figure(1)
imagesc(edge);
colormap gray;
hold on;
for i=1:size(y,1)
axis ij;
plot(y(i,:),x,'r','linewidth',1);
end
hold off;
endfunction
Thank you in advance.
You're definitely on the right track. Blurring the accumulator image would help before looking for the hotspots. Also, why not do a quick erode and dilate before doing the hough transform?
I had the same issue - detected lines had the correct slope but were shifted. The problem is that the r returned by the find(threshHough>0) function call is in the interval of [0,2*diag] while the Hough transform operates with values of r from the interval of [-diag,diag]. Therefore if you change the line
r=r/2
to
r=r-size(hough,1)/2
you will get the correct offset.
Lets define a vector of angles (in radians):
angles=pi*[0:360]/180
You should not take this operation: theta = theta/180*pi.
Replace it by: theta = angles(theta), where theta are indices
Some one commented above suggesting adjusting r to -diag to +diag range by
r=r-size(hough,1)/2
This worked well for me. However another difference was that I used the default angle to compute Hough Transform with angles -90 to +90. The theta range in the vector is +1 to +181. So It needs to be adjusted by -91, then convert to radian.
theta = (theta-91)*pi/180;
With above 2 changes, rest of the code works ok.

How to get the coordinates for a particular area or region in html5 canvas?

I created a circle using canvas and divided it into lines. I want the coordinate of a particular area: if I click a particular area, that alone should be clickable.
Take an example of a word wheel game where a circle is divided into many areas with different
coordinates and some letters placed inside the divided areas. If I want to click the particular area with the letter 'A', the 'A' should be clicked and should be displayed in a text box.
How do I accomplish this?
Hope the following gets you started.
Note that " the particular area with the letter 'A' " is called a sector of the circle.
Assume
the x axis is horizontal and positive to the right
the y axis is vertical and positive downwards
angles are measured in radians clockwise from the positive x axis
the first sector starts at angle A
centre of circle is at (cx,cy) and has radius r
the circle is divided into n equal sectors
the cursor is at the position (x,y)
the predefined function Math.atan2(y,x) returns the angle (from -pi and pi) between the positive x axis and the line segment from (0,0) to (x,y)
where i is and integer and i<= x < i+1 the predefined function Math.floor(x) returns i
Then
Let S be the angle at the centre for each sector
S=2*pi/n
Create a function getangle(x,y,cx,cy) which returns the angle from 0 and 2pi between the horizontal line through (cx,cy) in the positive x direction and the line segement from (cx,cy) to (x,y)
Pseudocode
function getangle(x,y,cx,cy)
{
var ang = Math.atan2(y-cy,x-cx)
if(ang<0)
{
ang+=2*Math.PI
}
return ang
}
Now you can create a function to check which sector, if any, the cursor lies in.
Return -1 if cursor is outside the circle, sector number from 1 to n otherwise.
Pseudocode
function isInSector(x,y) (x,y) coordinates of cursor
{
// first check if cursor is outside of circle
if((cx-x)*(cx-x)+(cy-y)*(cy-y)>r*r)
{
return -1
}
// find angle for cursor position
B=getangle(x,y,cx,cy)
return Math.floor((B-A)/S)+1
}

Create a function to generate random points in a parallelogram

I hope someone can help me here, I have been asked to write some code for an Lua script for a game. Firstly i am not an Lua Scripter and I am defiantly no mathematician.
What i need to do is generate random points within a parallelogram, so over time the entire parallelogram becomes filled. I have played with the scripting and had some success with the parallelogram (rectangle) positioned on a straight up and down or at 90 degrees. My problem comes when the parallelogram is rotated.
As you can see in the image, things are made even worse by the coordinates originating at the centre of the map area, and the parallelogram can be positioned anywhere within the map area. The parallelogram itself is defined by 3 pairs of coordinates, start_X and Start_Y, Height_X and Height_Y and finally Width_X and Width_Y. The random points generated need to be within the bounds of these coordinates regardless of position or orientation.
Map coordinates and example parallelogram
An example of coordinates are...
Start_X = 122.226
Start_Y = -523.541
Height_X = 144.113
Height_Y = -536.169
Width_X = 128.089
Width_Y = -513.825
In my script testing i have eliminated the decimals down to .5 as any smaller seems to have no effect on the final outcome. Also in real terms the start width and height could be in any orientation when in final use.
Is there anyone out there with the patients to explain what i need to do to get this working, my maths is pretty basic, so please be gentle.
Thanks for reading and in anticipation of a reply.
Ian
In Pseudocode
a= random number with 0<=a<=1
b= random number with 0<=b<=1
x= Start_X + a*(Width_X-Start_X) + b*(Height_X-Start_X)
y= Start_Y + a*(Width_Y-Start_Y) + b*(Height_Y-Start_Y)
this should make a random point at coordinates x,y within the parallelogram
The idea is that each point inside the parallelogram can be specified by saying how far you go from Start in the direction of the first edge (a) and how far you go in the direction of the second edge (b).
For example, if you have a=0, and b=0, then you do not move at all and are still at Start.
If you have a=1, and b=0, then you move to Width.
If you have a=1, and b=1, then you move to the opposite corner.
You can use something like "texture coordinates", which are in the range [0,1], to generate X,Y for a point inside your parallelogram. Then, you could generate random numbers (u,v) from range [0,1] and get a random point you want.
To explain this better, here is a picture:
The base is formed by vectors v1 and v2. The four points A,B,C,D represent the corners of the parallelogram. You can see the "texture coordinates" (which I will call u,v) of the points in parentheses, for example A is (0,0), D is (1,1). Every point inside the parallelogram will have coordinates within (0,0) and (1,1), for example the center of the parallelogram has coordinates (0.5,0.5).
To get the vectors v1,v2, you need to do vector subtraction: v1 = B - A, v2 = C - A. When you generate random coordinates u,v for a random point r, you can get back the X,Y using this vector formula: r = A + u*v1 + v*v2.
In Lua, you can do this as follows:
-- let's say that you have A,B,C,D defined as the four corners as {x=...,y=...}
-- (actually, you do not need D, as it is D=v1+v2)
-- returns the vector a+b
function add(a,b)
return {x = a.x + b.x, y = a.y + b.y} end
end
-- returns the vector a-b
function sub(a,b)
return {x = a.x - b.x, y = a.y - b.y} end
end
-- returns the vector v1*u + v2*v
function combine(v1,u,v2,v)
return {x = v1.x*u + v2.x*v, y = v1.y*u + v2.y*v}
end
-- returns a random point in parallelogram defined by 2 vectors and start
function randomPoint(s,v1,v2)
local u,v = math.random(), math.random() -- these are in range [0,1]
return add(s, combine(v1,u,v2,v))
end
v1 = sub(B,A) -- your basis vectors v1, v2
v2 = sub(C,A)
r = randomPoint(A,v1,v2) -- this will be in your parallelogram defined by A,B,C
Note that this will not work with your current layout - start, width, height. How do you want to handle rotation with these parameters?