Set Parent of Map Axes in Matlab GUI - maps

I am programming a basic GUI in MATLAB that utilizes the mapping toolbox. The GUI will display a grayscale image and then plot discrete points over the data, all of this over the necessary map projection. It is important that I plot onto map axes (those created by the axesm command) rather than the vanilla cartesian space. I have no problem doing all this from the command line, but I cannot find a way to implement a GUI version and its driving me nuts.
The problem is that I need to specify the map axes as being the child of the parent figure. The normal axes has a property that can be set, doing something like:
axesHandle = axes('Parent', parentHandle, ...);
or
set(axesHandle, 'Parent', parentHandle);
However, there is no equivalent parent property for the map axes created by the axesm function, so I have no way to manipulate the axes within the figure. How can I do this?
Update: If I create a plot within the map axes in an empty figure, get(figureHandle, 'Children') returns the handle of the axesm object (thanks #slayton!), so the map axes object must be implicitly added to the children of the figure by MATLAB.
Should I be concerned that the map axes do not refer back to the parent figure, or should I just let it be? I wonder if this is a classic case of MATLAB forcing me to not comply with the standards the manual tells me to implement.

From reading your question what I think you are trying to do is grab the handle of the axes object. This can be done as the axes is created using either axes or subplot
a = axes();
a = subplot(x,y,z);
% both return an handle to the newly created axes object
Additionally if the axes is created automagically by a function call like plot or image you can get the axes handle that too:
p = plot(1:10); %returns a handle to a line object
a = get(p,'Parent');
i = image(); %returns a handle to an image object
a = get(i, 'Parent');
Finally, neither of those two options is available you can always get the axes handle from its containing figure with:
a = get(figureHandle, 'Children');
Remember though that this will return a vector of axes handles if your figure contains more than one axes.
Finally when it comes time to draw draw your points to the axes that contains your map image you simply need to call:
line(xPoints, yPoints, 'linestyle', 'none', 'marker', '.', 'color', 'r', 'size', 15)
This will draw the vertices of the line using large red dots.
I'm not sure if this answers your question because the code you provided doesn't line up with the question you asked.
The code you provided looks like you are trying to move an axes from one figure to another. You can totally do this!
f = figure('Position', [100 100 100 100]);
a = axes('Parent', f);
pause
f2 = figure('Position', [250 100 100 100]);
set(a,'Parent', f2);

After much trial and error and reading of documentation, I have found that there is no way to explicitly specify the parent of the map axes. Instead, they are implicitly added on top of the current axes. In the instance that no axes exist in the current figure, calling axesm creates an axes object and then places the axesm object inside. When you take this route, you have to grab the axes object handle by calling gca:
mapAxesHandle = axesm(...);
axesHandle = gca(...);
This makes it frustrating to use the mapping toolbox when writing a GUI from scratch, but that's the way Mathworks makes it happen. Thanks to #slayton for useful info. I'd upvote but my reputation is <15 :(

Related

How to mark some grid points on netcdf map?

I can make 2D dimensional netcdf maps of some quantity. I open it in panoply and there is color map of that quantity. But I cannot visualize some boolean value.
Can I somehow mark particular grid points with some symbol on the map (it can be diamond, square, triangle... whatever), is there a way how to do it in Fortran90? I accept also python related help.
Again: I mean there would be color map (from real values) (which I can do) and at the same time some values will have e. g. triangle on it.
If I understand the question correctly, then you can easily do that with Python and using some plotting library (e.g Matplotlib). With Fortran it is extremely tricky as it does not natively support plotting in my mind.
Basically with Python you just have to :
read the wanted variables (coordinates and the field itself)
make the map of the field i.e make the plot
find the locations you want to highlight and just add those locations to the plot

How to get my MapContainer bounding box in Codename One

My Codename One app features a MapContainer. I need to show points of interest (POIs) on it which coordinates reside on the server. There can be hundreds (maybe thousands in the future) of such POIs on the server. That's why I would like to only download from the server the POIs that can be shown on the map. Consequently I need to get the map boundaries to pass them to the server.
I read this for Android and this other SO question for iOS and the key seems to get the map Projection and the map bounding box. However the getProjection() method or the getBoundingBox() seem not to be exposed.
A solution could be to mix the coordinates from getCameraLocation() which is the map center and getZoom() to infer those boundaries. But it may vary depending on the device (see the shown area can be larger).
How can get the map boundaries in Codename one ?
Any help appreciated,
Cheers,
The problem is in the javadocs for getCoordAtPosition(). This will be corrected. getCoordAtPosition() expects absolute coordinates, not relative.
E.g
Coord NE = currentMap.getCoordAtPosition(currentMap.getWidth(), 0);
Coord SW = currentMap.getCoordAtPosition(0, currentMap.getHeight());
Should be
Coord NE = currentMap.getCoordAtPosition(currentMap.getAbsoluteX() + currentMap.getWidth(), currentMap.getAbsoluteY());
Coord SW = currentMap.getCoordAtPosition(currentMap.getAbsoluteX(), currentMap.getAbsoluteY() + currentMap.getHeight());
I tried this out on the coordinates that you provided and it returns valid results.
EDIT March 21, 2017 : It turns out that some of the platforms expected relative coordinates, and others expected absolute coordinates. I have had to standardize it, and I have chosen to use relative coordinates across all platforms to be consistent with the Javadocs. So your first attempt:
Coord NE = currentMap.getCoordAtPosition(currentMap.getWidth(), 0);
Coord SW = currentMap.getCoordAtPosition(0, currentMap.getHeight());
Will now work in the latest version of the library.
I have also added another method : getBoundingBox() that will get the bounding box for you without worrying about relative/absolute coordinates.
This is probably something that can be exposed easily by forking the project and providing a pull request. We're currently working on updating the map component so this is a good time to make changes and add features.

Esri Silverlight control Pan/Zoom from code

I have trouble getting Map behave properly when calling ZoomToResolution and PanTo
I need to be able to Zoom into specific coordinate and center map.
The only way I got it working is by removing animations:
this.MapControl.ZoomDuration = new TimeSpan(0);
this.MapControl.PanDuration = new TimeSpan(0);
Otherwise if I make call like this:
control.MapControl.ZoomToResolution(ZoomLevel);
control.MapControl.PanTo(MapPoint());
It does one or another (i.e. pan or zoom, but not both). If (after animation) I call this code second time (map already zoomed or panned to needed position/level) - it does second part.
Tried this:
control.MapControl.ZoomToResolution(ZoomLevel, MapPoint());
Same issue, internally it calls above commands
So, my only workaround right now is to set Zoom/Pan duration to 0. And it makes for bad UX when using mouse.
I also tried something like this:
this.MapControl.ZoomDuration = new TimeSpan(0);
this.MapControl.PanDuration = new TimeSpan(0);
control.MapControl.ZoomToResolution(ZoomLevel);
control.MapControl.PanTo(MapPoint());
this.MapControl.ZoomDuration = new TimeSpan(750);
this.MapControl.PanDuration = new TimeSpan(750);
Which seems to be working, but then mouse interaction becomes "crazy". Mouse scroll will make map jump and zoom to random places.
Is there known solution?
The problem is the second operation replaces the previous one. You would have to wait for one to complete before starting the next one. But that probably doesn't give the effect you want.
Instead zoom to an extent, and you'll get the desired behavior. If you don't have the extent but only center and resolution, you can create one using the following:
var zoomToExtent = new Envelope(point.X - resolution * MapControl.ActualWidth/2, point.Y, point.X + resolution * MapControl.ActualWidth/2, point.Y);
Btw it's a little confusing in your code that you call your resolution "ZoomLevel". I assume this is a map resolution, and not a level number right? The esri map control doesn't deal with service-specific levels, but is agnostic to the data's levels and uses a more generic "units per pixels" resolution value.

How can I combine UIBezierPath drawings?

I'm trying to combine several UIBezierPath drawings.
I have different types of drawings I can make (line, cubic bezier, quadratic beziers), and each of these can be filled or unfilled. I'm selecting the drawing type randomly, and my goal is to make 3 different drawings which are connected at a point.
So where the first, say, line drawing ends, the second path - maybe a cubic bezier — begins. Where that ends, a third, maybe a filled line drawing begins.
I've got a square UIView that I'm trying to draw this in, and each path should have its own part of the UIView: the first 1/3rd, the second and the third.
Would I be able to create this with one UIBezierPath object, or do I need to create 3 different ones? How to make them end and start at the same point? Is there a way to do this with subpaths?
UIBezierPath has its instance methods like (DOC)
-addLineToPoint:
-addArcWithCenter:radius:startAngle:endAngle:clockwise:
-addCurveToPoint:controlPoint1:controlPoint2:
-addQuadCurveToPoint:controlPoint:
-appendPath:
You can combine paths one by one. When you've done, use -closePath to close the path.
Feel free to take a look at my open sourced lib which called UIBezierPath-Symbol. ;)
And if you want more customise path drawing, I recommend CGMutablePath. You can create each path as complex as you want (you can combine simple paths by CGPathAdd... methods). Finally, use CGPathAddPath() to combine them together.
void CGPathAddPath (
CGMutablePathRef path1, // The mutable path to change.
const CGAffineTransform *m, // A pointer to an affine transformation matrix, or NULL if no transformation is needed. If > specified, Quartz applies the transformation to path2 before it is added to path1.
CGPathRef path2 // The path to add.
);
You can combine paths like this:
UIBezierPath *endPath = [UIBezierPath bezierPath];
[endPath appendPath:leftLine];
[endPath appendPath:rightLine];
[endPath appendPath:midLine];
A UIBezierPath is just a wrapper for a CGPath, which itself is just a set of instructions for drawing (by stroke or fill, or both). That drawing can take place anywhere. In other words, a UIBezierPath is just a tool for drawing; the important thing is the drawing itself. Given a graphics context (which might be a UIView, a UIImage, a CALayer, whatever), you can do as much drawing as you like in succession - say, a line, then a cubic bezier, then a filled line drawing. But how you perform those drawing bits is totally up to you. You shouldn't really care whether you do it with three UIBezierPaths, one UIBezierPath, multiple paths, one path, subpaths, whatever (or even by copying other drawings into this one) - the final effect is all that matters, i.e. the accumulated drawing ultimately done in this graphics context.
Your question is like asking, "Should I draw this circle with my right hand or my left hand, and should I draw it counter-clockwise or clockwise?" It doesn't matter. Once it's done, what will have been drawn is a circle; that is what's important.

Displaying an Elevation grid in ParaView

I'm new to ParaView and completely lost with all the different data formats. All I want to do is display an elevation grid which is produced by a program. I store the elevation grid in a two dimensional array of floats which is indexed by x and y coordinates and stores the z coordinate. In other words elevationGrid[x][y] stores the height above the point (x, y).
Which file format should I use for this and how is it defined? It would be ideal if someone could give an example file for, say, a 3x3 grid.
A first approach with a 5x5 grid and equation z = x^2+y^2, using a very simple input format. This is a general approach, not especially dedicated to structured grid.
The following has been done with Paraview 3.14.1.
1) Save your data in csv format, i.e. :
"x","y","z"
-0.5,-0.5,0.5
-0.30000001,-0.5,0.34000001
-0.1,-0.5,0.26
[...]
0.1,0.5,0.26
0.30000001,0.5,0.34000001
0.5,0.5,0.5
2) Open in Paraview your csv file
Fill the required import options.
3) Convert your table to geometrical points
Apply Filters > Alphabetical > Table to points
You will be asked to give each variables for each coordinates.
4) Display 3D view to see your points
Create a new visualization view (add a new tab) and choose "3D View".
Activate your TableToPoints filter clicking on the little eye near its name in the pipeline.
If evething is okay, at this point you will see your scatter plot.
5) Last step: create a surface
Apply Filters > Alphabetical > Delaunay 2D
And using default options, one finally obtains:
EDIT:
I remember the name of the dedicated function to create elevation map... It is the Wrap by scalar function. You can combine it with some above steps to get more easily what you want. I could give you an example if necessary.

Resources