I'm currently creating a map in Openlayers for a customer that requires validation for drawing polygons inside another polygon (base-area). By using JSTS and Openlayers native methods, i'm able to validate that all shapes are drawn inside the polygon, and do not intersect with other shapes inside the polygon. This includes markers and polygons.
Another requirement is to check if the base-area is completely filled by other polygons, with pre-defined margins. I've not been able to think of any way to do this yet. What would be a good way to accomplish this?
EDIT:
Methods i used to check if polygon contains other polygon:
const geoJSONFormat = new GeoJSON();
const jstsGeoJSONReader = new jsts.io.GeoJSONReader();`
polygon1 = jstsGeoJSONReader.read(geoJSONFormat.writeFeatureObject(feature1)).geometry;
polygon2 = jstsGeoJSONReader.read(geoJSONFormat.writeFeatureObject(feature2)).geometry;
polygon1ContainsPolygon2= polygon1.contains(polygon2); `
First i pass the given feature the geoJSONFormat.writeFeatureObject which is imported from OL. And then assign this to a variable using the JSTS GeoJSON-reader.
contains-method from JSTS will return a boolean indicating if polygon2 is contained inside polygon1
Since you've already validated the polygons are inside the base-area and that they aren't overlapping. To check the base-area is completely filled, just check the sum of the area of the polygons is equal to the base-area.
I'm not entirely sure what you mean by margin but you could check the sum of the area of the polygons is at least some x% of the area of the base-area to give some "wiggle" room.
Related
I'm implementing the class diagram where the users can change the class' name, attributes and methods. I'm having trouble with resizing the class rectangle width depending on name, attribute or method length. These can overflow and go outside the rectangle, and I just can't find a method to get the correct size.
I also have added an element tool to the elementView, and set its x and y to "100%". According to documentation: "Use percentage strings (e.g. '40%') to position the button relatively to the element width/height." but I guess this isn't the model's size, as I typed JSON.stringify(graph.toJSON()) and got the following.
JSON.stringify(graph.toJSON())
The size is the default value I set (260x100).
I checked the size of the attribute using DevTools:
Size of attribute
The gray button detects the width number I need (330), so I guess that the x in element tools is the elementView's width. I looked at the documentation and can't find any method like .size() or .getSize() for the elementView. I need to resize the rectangle to the size of Max(name length, attribute length, method length) + some aditional space to not look cramped up. I have seen some solutions like "Use [number of letters] * [some constant]" but that is no good as typing 5 "W"s doesn't take the same space as typing 5 "i"s.
So how do I get the width of the whole element (in my case 330 from text length + the three pixels from the left border of the rectangle to the first text letter)?
Okay, so after searching through several Google Groups chats I found some pieces of code that helped me.
For getting the width I needed, I used elementView.getBBox().width.
Where I didn't have the element view right at hand, I at least had the model ID, and so I used paper.findViewByModel(modelId) to get the element view.
I want to make a Rubik's cube with VPython and I've faced a problem in the first stage! I want to color every face of a box with a different color but I can't find that! In the tutorial you only can color all of the faces of the box with one certain color!
What should I do?
Note: I'm using VPython 7 and Python 3.6
You can also make a box with different colored faces using a compound object made up of 6 pyramid objects each of a different color.
def cubelet(....): # a "factory function"
#create a list of the 6 pyramids with different colors; suppose its name is L
L = [pyramid(color=color.red,pos=vec(),axis=vec()), ... ]
return compound(L)
c = cubelet(....)
This "factory function" (a function that returns an object) returns an object that has the usual properties of primitive objects such as box. You can manipulate this compound object by changing c.pos or c.axis, etc. You can create copies of this cubelet:
c2 = c.clone(pos=vec(10,5,0), size=vec(2,1,0.2))
For pyramid see documentation
http://www.glowscript.org/docs/VPythonDocs/pyramid.html
Just arrange 6 of these in the shape of a box. For compound object see
http://www.glowscript.org/docs/VPythonDocs/compound.html
to make a compound object out of 6 pyramids.
You can try make a box with different color faces out of 6 boxes similar to what is shown in this demo, where the box has red blue and grey faces.
http://www.glowscript.org/#/user/GlowScriptDemos/folder/Examples/program/Bounce-VPython
You can also make a compound object out of a number of objects.
http://www.glowscript.org/docs/VPythonDocs/compound.html
So you can make a compound object called multicolored box made out of six boxes of different colors.
You can also try creating your own box out of triangles and/or quads and color each face.
http://www.glowscript.org/docs/VPythonDocs/triangle.html
In fabric.js when a Polygon object is moved, scaled, or rotated via mouse cursor manipulation, the Polygon's original points array elements are not updated to reflect their new "true" current positions on the canvas.
This is problematic in my application, where we allow adding points to an existing polygon via clicks on the canvas, by taking the points array of the existing object, removing the existing object from the canvas, adding the new point to the points array, and creating a new polygon object with those points. This works fine if the polygon was not manipulated by the user.
Is there a way to, using the object:modified event, recreate the polygon updating its points to reflect their new true positions, taking into account the object's new position, scaling, and rotation?
I just started out with Phaser.
I have a simple sprite in the middle of the screen, and whenever I click the sprite, I emit a particle at the clicked x,y coordinates.
My problem is that the particles are generated behind the sprite. I have tried setting z on the sprite to 1 and the emitter to 1000 without luck.
What am I missing?
var emitter = game.add.emitter(game.world.centerX, game.world.centeryY);
emitter.makeParticles('phaser');
var sprite = game.add.sprite(game.world.centerX, game.world.centerY, 'phaser');
sprite.scale.setTo(2, 2);
sprite.inputEnabled = true;
sprite.events.onInputDown.add(function(sender, pointer){
emitter.emitX = pointer.x;
emitter.emitY = pointer.y;
emitter.emitParticle();
}, this);
http://phaser.io/sandbox/cxBVeHrx
EDIT
My actual code is based on the Phaser-ES6-Boilerplate. Even though BdRs answer solves the issue in the sandbox code, I'm not able to utilize this in my real code.
I have uploaded both the code and a running example. Hopefully someone can tell me where I have screwed things up...
Separate Phaser items don't have a z-order, instead it just depends on the order you create and add them to game. Each new sprite or emitter or group etc. will be displayed on top of all previously added items.
So, simply changing your code to something like this should work.
// first the sprite
var sprite = game.add.sprite(game.world.centerX, game.world.centerY, 'phaser');
sprite.scale.setTo(2, 2);
// then the particles in front of sprite
var emitter = game.add.emitter(game.world.centerX, game.world.centeryY);
emitter.makeParticles('phaser');
// then maybe text in front of particles and sprite
var mytest = game.add.bitmapText(10, 20, 'myfont', 'Level 1', 16);
// etc.
Btw sprites do have a .z value but that only used when it's part of a Phaser.Group, it will then be used as the display z-order but only within that group of sprites.
By default, phaser will not sort objects that get added to any group, it will just render them in the order that they get added. In your case, you can just add the emitter to the group after you add the sprite (the group in this case is the 'game' object).
Of course, having to add objects in the drawing order is not ideal, and if you need to have them sorted dynamically, not possible.
Another way is you can sort objects within a group using the 'sort' function, in which you give it the name of a parameter to sort by, and you sort whenever you need to (in some cases, in the Update callback).
Sorting every frame can be a performance hit though, especially if you have a lot of objects. Another way you could go about this is by adding groups, sorting those groups in draw order (think of them like layers), and then adding objects to those groups in any order. Any group that needs sorting within itself you can sort as well. This way, you can choose to have (for example) a background layer not needing to be sorted but everything added to that layer will be behind every other layer.
Good answers from everybody, but you are missing that every GameObject has a depth property which serves exactly the z-index purpose. This way you do not need to rely on the order of objects creation.
There is also an official
example.
Hope this helps.
I've a layer with multiple markers with rather big icons, so they overlap. Via the list on the side of the map users can select a marker and the map will pan (and zoom) to it. But it will still be behind some other makers.
How do I get a individual makers z-index and set it? I would be useful to get the highest used z-index and just add one. (another solution is to add the total number of markers to the z-index)
The markers (or features) are in a myLib.features array. The console doesn't show any z-index type functions.
I can't find a appropriate example or api function for this.
EDIT:
I found this example: http://dev.openlayers.org/examples/ordering.html
I don't really understand it. Somehow the created feature takes the next z-index given by the layer via somekind of symbolizer. I have no idea how to work this static sort into a dynamic one.
Try this:
First of all, make sure you are using a OpenLayers.Layer.Vector layer, not a OpenLayers.Layer.Markers layer. Apparently the Markers layer is old news and all new development is done in the Vector layer. It has more features. (I wasted a pile of time with the Markers layer myself).
Then, each of your markers needs to be a OpenLayers.Feature.Vector object. The constructor takes three arguments, the third of which is called the style. The style is where you set your image attributes, the background shadow, the mouse-over text, and the z-index, which has the property name "graphicZIndex". I think that's what you're looking for.
http://dev.openlayers.org/releases/OpenLayers-2.12/doc/apidocs/files/OpenLayers/Feature/Vector-js.html#OpenLayers.Feature.Vector.OpenLayers.Feature.Vector.style
Add your "markers" (which are Vector's) to your Vector layer with the addFeatures function. And just ignore the "options" argument.
http://dev.openlayers.org/releases/OpenLayers-2.12/doc/apidocs/files/OpenLayers/Layer/Vector-js.html#OpenLayers.Layer.Vector.addFeatures
I found that example page too, and I found it confusing too. It was setting all the markers' styles in the Vector layer's constructor (as default values to be used if the marker style was omitted) instead of the marker's constructor. I think it makes more sense to set the marker style in the marker constructor.
To change the style in real-time, take one of your OpenLayers.Feature.Vector markers, called "marker" and do this. And let's call the Vector Layer "layer".
marker.style.graphicZIndex = 13;
layer.redraw();