Mystery coordinate offset on getCharBoundaries - apache-flex

I've ran into a weird problem with getCharBoundaries, I could not figure out what coordinate space the coordinates returned from the function was in. What ever I tried I could not get it to match up with what I expected.
So I made a new project and and added simple code to highlight the last charater in a textfield, and all of a sudden it worked fine. I then tried to copy over the TextField that had been causing me problems, into the new project. And now the same weird offset appeared 50px on the x axis. Everything else was spot on.
So after some headscracthing comparing the two TextFields, I simply can not see a difference in their properties or transformation.
So I was hoping that someone might now what property might affect the coordinates returned by getCharBoundaries.
I am using Flash CS4.

I've just had exactly the same problem and thought I'd help out by offering what my findings are. With a help from this thread, I tried to find everything that wasn't 'default' about the textfield I was using. I found that when I had switched my TextFormatAlign (or 'align' in the IDE) and TextFieldAutoSize properties to 'LEFT' as opposed to 'CENTER', it solved the problem.
A little late in the game perhaps, but worth knowing for anyone running into the same problem. This was the only thread I could find that raised the right flag...

Well the getCharBoundaries returns the boundaries in the textfield coordinate system. Where the origin is topleft corner of the textfield.
getCharBoundaries does not take into consideration the scrolling. you need to check if there are scrollbars on its parent (textarea) and if so relocate. One quick way of doing it is using localtoglobal and globaltolocal. Use the first to translate from the textfield coordinate system to the application coordinate system and then use the second to translate from the app coordinate system to the coordinate system of the parent of the textfield which is the textarea. I'm fine tuning a my method to get char boundaries i will publish it today on my blog
http://flexbuzz.blogspot.com/

Works For Me(tm) (Flex Builder AS3 project):
[Embed(systemFont="Segoe UI", fontWeight="bold", fontName="emb",
mimeType="application/x-font")]
private var EmbeddedFont:Class;
public function ScratchAs3()
{
stage.scaleMode = 'noScale';
stage.align = 'tl';
var m:Matrix = new Matrix(.8, .1, -.1, 1.1, 26, 78);
var t:TextField = new TextField();
t.autoSize = 'left';
t.wordWrap = false;
t.embedFonts = true;
t.defaultTextFormat = new TextFormat("emb", 100, 0, true);
t.transform.matrix = m;
t.text = "TEST STRING.";
addChild(t);
var r:Rectangle = t.getCharBoundaries(8);
var tl:Point = m.transformPoint(r.topLeft);
var tr:Point = m.transformPoint(new Point(r.right, r.top));
var bl:Point = m.transformPoint(new Point(r.left, r.bottom));
var br:Point = m.transformPoint(r.bottomRight);
graphics.beginFill(0xFF, .6);
graphics.moveTo(tl.x, tl.y);
graphics.lineTo(tr.x, tr.y);
graphics.lineTo(br.x, br.y);
graphics.lineTo(bl.x, bl.y);
graphics.lineTo(tl.x, tl.y);
}
To literally answer your question, it returns the coordinates in the TextField's coordinate system, not it's parent, and it is affected by DisplayObject.transform.matrix, which is the backing for the .x, .y, .scaleX, .scaleY, .width, .height, and .rotation properties.

What ever it was the solution was simple to add a new TextField, never found out what property screwed everything up.

The first answer is correct in most cases. However if your field is parented to another movie clip it may still return the wrong y coordinate. try this code:
//if this doesn't work:
myTextFormat = new TextFormat();
myTextFormat.align = TextFormatAlign.LEFT;
myFieldsParent.myField.autoSize = TextFieldAutoSize.LEFT;
myFieldsParent.myField.setTextFormat( myTextFormat);
//try this:
var x = myFieldsParent.myField.getCharBoundaries(o).x;
var y = myFieldsParent.myField.getCharBoundaries(o).y;
var myPoint:Point = new Point(myField.getCharBoundaries(o).x,myField.getCharBoundaries(o).y);
var pt:Point = new Point(myFieldsParent.myField.getCharBoundaries(o).x, myFieldsParent.myField.getCharBoundaries(o).y);
pt = myFieldsParent.myField.localToGlobal(pt);
//pt is the variable containing the coordinates of the char in the stage's coordinate space. You may still need to offset it with a fixed value but it should be constant.
I didn't test this code as I have adapted this example from code that is embedded into my project so I apologize if I'm missing something...

Related

HERE MAP add new point in clicked place on polyline

I really beg about help because I'm trying to do some things for a few days, and I really don't know how. I want to do road manipulate by hold and drag . I think I need to start with adding new point in polyline geometry exaclly in the pointer place (or linestring, linstring points and polyline geometry seems to be almost the same). But it seems to be impossible.
Of course, there is no problem with getting coordinates, but adding this new coordinates to polyline or linestring in appropriate place.
There is no code, because every here map methods (pushPoints, setGeopetry) seems to be usless, and give points in the wrong place.
See please this example: https://demo.support.here.com/examples/v3/fleet - you can drag-n-drop there
and src code of it : https://demo.support.here.com/javascripts/examples/v3/fleet.js
Search there in the code the variable clipedPolyline and func clipPolyline:
var clipPolyline = function(polyline, viewportX, viewportY, bboxSize){
var pleft = viewportX - bboxSize,
pright = viewportX + bboxSize,
ptop = viewportY - bboxSize,
pbottom = viewportY + bboxSize,
coordLeftTop = map.screenToGeo(pleft, ptop),
coordRigthBottom = map.screenToGeo(pright, pbottom),
rect = new H.geo.Rect(coordLeftTop.lat,coordLeftTop.lng,coordRigthBottom.lat,coordRigthBottom.lng),
clipedPolyline = polyline.clip(rect);
return clipedPolyline;
};
Read please documentation for method clip on:
https://developer.here.com/documentation/maps/3.1.31.0/api_reference/H.map.Polyline.html#clip

How to add fontawasome icon as a layer in geotools using javafx (Desktop App)?

I have been using java 17 and I'm unable to add icons into the map as a layer. please help me.
void drawTarget(double x, double y) {
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName("MyFeatureType");
builder.setCRS( DefaultGeographicCRS.WGS84 ); // set crs
builder.add("location", LineString.class); // add geometry
// build the type
SimpleFeatureType TYPE = builder.buildFeatureType();
// create features using the type defined
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
// GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
// Coordinate[] coords =
// new Coordinate[] {new Coordinate(79,25.00), new Coordinate(x, y)};
// line = geometryFactory.createLineString(coords);
// ln = new javafx.scene.shape.Line();
FontAwesomeIcon faico = new FontAwesomeIcon();
faico.setIconName("FIGHTER_JET");
faico.setX(76);
faico.setY(25);
faico.setVisible(true);
// TranslateTransition trans = new TranslateTransition();
// trans.setNode(faico);
featureBuilder.add(faico);
SimpleFeature feature = featureBuilder.buildFeature("FeaturePoint");
DefaultFeatureCollection featureCollection = new DefaultFeatureCollection("external", TYPE);
featureCollection.add(feature); // Add feature 1, 2, 3, etc
Style style5 = SLD.createLineStyle(Color.YELLOW, 2f);
Layer layer5 = new FeatureLayer(featureCollection, style5);
map.addLayer(layer5);
// mapFrame.getMapPane().repaint();
}
I want to add a font-awesome icon to the map
Currently, your code is attempting to use an Icon as a Geometry in your feature. I'm guessing that's what isn't working since you don't say.
If you want to use an Icon to display the location of a Feature then you will need two things.
A valid geometry in your feature, probably a point (since an Icon is normally a point)
A valid Style to be used by the Renderer to draw your feature(s) on the map. Currently, you are asking for the line in your feature to be drawn using a yellow line (style5 = SLD.createLineStyle(Color.YELLOW, 2f);)
I can't really help with step 1, since I don't know where your fighter jet currently is.
For step 2 I suggest you look at the SLD resources to give you some clues of how the styling system works before going on the manual to see how GeoTools implements that.
Since you are trying to add an Icon I suggest you'd need something like:
List<GraphicalSymbol> symbols = new ArrayList<>();
symbols.add(sf.externalGraphic(svg, "svg", null)); // svg preferred
symbols.add(sf.externalGraphic(png, "png", null)); // png preferred
symbols.add(sf.mark(ff.literal("circle"), fill, stroke)); // simple circle backup plan
Expression opacity = null; // use default
Expression size = ff.literal(10);
Expression rotation = null; // use default
AnchorPoint anchor = null; // use default
Displacement displacement = null; // use default
// define a point symbolizer of a small circle
Graphic city = sf.graphic(symbols, opacity, size, rotation, anchor, displacement);
PointSymbolizer pointSymbolizer =
sf.pointSymbolizer("point", ff.property("the_geom"), null, null, city);
rule1.symbolizers().add(pointSymbolizer);
featureTypeStyle.rules().add(rule1);
But that assumes that you can convert your FontAwesomeIcon into a static representation that the renderer can draw (png, svg). If it doesn't work like that (I don't use JavaFX) then you may need to add a new MarkFactory to handle them.

Zoom into group of points in Flex

I have an application in Flex 4 with a map, a database of points and a search tool.
When the user types something and does the search it returns name, details and coordinates of the objects in my database.
I have a function that, when i click one of the results of my search, it zooms the selected point of the map.
The question is, i want a function that zooms all the result points at once. For example if i search "tall trees" and it returns 10 points, i want that the map zooms to a position where i can see the 10 points at once.
Below is the code im using to zoom one point at a time, i thought flex would have some kind of function "zoom to group of points", but i cant find anything like this.
private function ResultDG_Click(event:ListEvent):void
{
if (event.rowIndex < 0) return;
var obj:Object = ResultDG.selectedItem;
if (lastIdentifyResultGraphic != null)
{
graphicsLayer.remove(lastIdentifyResultGraphic);
}
if (obj != null)
{
lastIdentifyResultGraphic = obj.graphic as Graphic;
switch (lastIdentifyResultGraphic.geometry.type)
{
case Geometry.MAPPOINT:
lastIdentifyResultGraphic.symbol = objPointSymbol
_map.extent = new Extent((lastIdentifyResultGraphic.geometry as MapPoint).x-0.05,(lastIdentifyResultGraphic.geometry as MapPoint).y-0.05,(lastIdentifyResultGraphic.geometry as MapPoint).x+0.05,(lastIdentifyResultGraphic.geometry as MapPoint).y+0.05,new SpatialReference(29101)).expand(0.001);
break;
case Geometry.POLYLINE:
lastIdentifyResultGraphic.symbol = objPolyLineSymbol;
_map.extent = lastIdentifyResultGraphic.geometry.extent.expand(0.001);
break;
case Geometry.POLYGON:
lastIdentifyResultGraphic.symbol = objPolygonSymbol;
_map.extent = lastIdentifyResultGraphic.geometry.extent.expand(0.001);
break;
}
graphicsLayer.add(lastIdentifyResultGraphic);
}
}
See the GraphicUtil class from com.esri.ags.Utils package. You can use the method "getGraphicsExtent" to generate an extent from an array of Graphics. You then use the extent to set the zoom factor of your map :
var graphics:ArrayCollection = graphicsLayer.graphicProvider as ArrayCollection;
var graphicsArr:Array = graphics.toArray();
// Create an extent from the currently selected graphics
var uExtent:Extent;
uExtent = GraphicUtil.getGraphicsExtent(graphicsArr);
// Zoom to extent created
if (uExtent)
{
map.extent = uExtent;
}
In this case, it would zoom to the full content of your graphics layer. You can always create an array containing only the features you want to zoom to. If you find that the zoom is too close to your data, you can also use map.zoomOut() after setting the extent.
Note: Be careful if you'Ve got TextSymbols in your graphics, it will break the GraphicUtil. In this case you need to filter out the Graphics with TextSymbols
Derp : Did not see the thread was 5 months old... Hope my answer helps other people

Applying blur filter to BitmapData

Here's the code I am using to blur an image using BitmapData. The function is called on a Slider_changeHandler(event:Event):voidevent and the value of the slider is passed to the function as blurvalue.
The problem is the function works but seems to be cummalative (if that's the correct word!), that is, suppose I slide it to the maximum and after that try to reduce the blur by sliding it back towards the front the blur still keeps increasing. How do I make it to work so when I will slide it up blur increases and when I slide it back blur decreases and when slider is at 0, no blur is applied.
var blur:BlurFilter = new BlurFilter();
blur.blurX = blurvalue;
blur.blurY = blurvalue;
blur.quality = BitmapFilterQuality.MEDIUM;
bitmapdata.applyFilter(bitmapdata,new
Rectangle(0,0,bitmapdata.width,bitmapdata.height),new Point(0,0),
blur);
return bitmapdata;
how about returning a clone of the original bitmapData with the filter applied ?
e.g.
var result:BitmapData = bitmapdata.clone();
var blur:BlurFilter = new BlurFilter();
blur.blurX = blurvalue;
blur.blurY = blurvalue;
blur.quality = BitmapFilterQuality.MEDIUM;
result.applyFilter(result,new
Rectangle(0,0,bitmapdata.width,bitmapdata.height),new Point(0,0),blur);
return result;
Also, if you're using the BlurFilter, you might need a larger rectangle, depending on the amount of blur. For that, you can use the generateFilterRect() method to get correct sized rectangle for the filter.
If I were you, I'd take the BitmapData and put it in a Bitmap object, then add the filters:
var bitmap:Bitmap = new Bitmap(bitmapData);
var blur:BlurFilter = new BlurFilter();
blur.blurX = blurvalue;
blur.blurY = blurvalue;
blur.quality = BitmapFilterQuality.MEDIUM;
bitmap.filters = [blur];
By doing this (interchanging the filters array), you're not making the filters cumulative.

Getting the global coordinate of a Node in JavaFX

How can I get the actual position of a node in the scene. The absolute position, regardless of any containers/transforms.
For example, I want to translate a certain node a so that it would temporarily overlap another node b. So I wish to set his translateX property to b.globalX-a.globalX.
The documentation says:
Defines the X coordinate of the
translation that is added to the
transformed coordinates of this Node
for the purpose of layout. Containers
or Groups performing layout will set
this variable relative to
layoutBounds.minX in order to position
the node at the desired layout
location.
For example, if child should have a
final location of finalX:
child.layoutX = finalX - child.layoutBounds.minX;
That is, the final coordinates of any node should be
finalX = node.layoutX + node.layoutBounds.minX
However running the following code:
var rect;
Stage {
title: "Application title"
width: 250
height:250
scene: Scene {
content: [
Stack{content:[rect = Rectangle { width:10 height:10}] layoutX:10}
]
}
}
println("finalX = {rect.layoutX+rect.layoutBounds.minX}");
gives me finalX = 0.0 instead of finalX = 10.0 as the docs seemingly state.
Is there a clear method to get the absolutely final positioning coordinates in JavaFX?
For bounds:
bounds = rect.localToScene(rect.getBoundsInLocal());
Work for JavaFx 1 and 2.
The only solution I found so far is
rect.localToScene(rect.layoutBounds.minX, rect.layoutBounds.minY) // a Point2D{x:Float y:Float} object
Which doesn't seem to me as the "best" way to do that (note that this function is not bound). Still it works for JavaFX 1.2.
Since JavaFX 8, there are additional methods converting local coordinates to screen coordinates. Their names start with "localToScreen"
You can check following link
http://docs.oracle.com/javase/8/javafx/api/javafx/scene/Node.html#localToScreen-double-double-

Resources