I create plots based on worldguard regions. I am looking for a good method of checking if there is no other region within a radius of 50 counts in each direction. My point is that someone does not create a plot and someone else's plot. Currently, I checked it in a strange way for me, but it practically worked.
Location p3 = p.getLocation();
p3.setX(p3.getBlockX());
p3.setY(60);
p3.setZ(p3.getBlockZ()+size);
if(region.getApplicableRegions(p3).size() == 0) {
plotsCheck.put(p.getUniqueId(), plotsCheck.get(p.getUniqueId())+1);
}
Location p3a = p.getLocation();
p3a.setX(p3a.getBlockX());
p3a.setY(60);
p3a.setZ(p3a.getBlockZ()+10);
if(region.getApplicableRegions(p3a).size() == 0) {
plotsCheck.put(p.getUniqueId(), plotsCheck.get(p.getUniqueId())+1);
}
Location p4 = p.getLocation();
p4.setX(p4.getBlockX());
p4.setY(60);
p4.setZ(p4.getBlockZ()-size);
if(region.getApplicableRegions(p4).size() == 0) {
plotsCheck.put(p.getUniqueId(), plotsCheck.get(p.getUniqueId())+1);
}
In this way, I checked if it was empty. If so, I added 1 point to the hashmap.
Unfortunately, this does not always work and ends with the fact that several plot plots belong to 2 people. Does anyone of you propose a different solution for this?
WorldGuard already has some built in features for that.
RegionContainer container = getWorldGuard().getRegionContainer();
RegionManager manager = container.get(world);
Region newRegion = //create your region somehow
manager.addRegion(newRegion);
List<ProtectedRegion> regions = new ArrayList<ProtectedRegion>(manager.getRegions().values());
List<ProtectedRegion> overlappingRegions = newRegion.getIntersectingRegions(regions);
if (overlappingRegions.size() > 0) {
//delete region newRegion
} else {
//region is valid
}
This of course works only after the region has already been created.
Code has not been tested. Just searched through the WorldGuard API wiki.
https://worldguard.enginehub.org/en/latest/developer/regions/protected-region/#finding-intersecting-regions
Related
I am writing an app that generates Maths worksheets for school students. It will, for example, generate 2 to 5 pages of simple Maths questions and 1 to 2 pages of answers. The PDF can be saved to file and loaded again later. Then it has a print function that can print all the pages. I want to make it skip printing the answer pages.
Is it possible to automatically identify which pages are the answer pages? I can only think of a workaround by making those answer pages have special height or width but not even sure if this works. Are there any better ways to do this?
Ok, I continued the project and used the following method: when constructing the PDF, I put the word "Answer on the top left corner with a gray rectangle surrounding it drawn with drawRect(). Then before the actual printing, I used the following code inside the PrintDocumentAdapter() class to check whether the color of the pixel 0,0 is gray or not.
#Override
public void onStart() {
if (parcelFileDescriptor != null) {
try {
pdfRenderer = new PdfRenderer(parcelFileDescriptor);
} catch (IOException e) {
e.printStackTrace();
}
}
int tempTotal = pdfRenderer.getPageCount();
Bitmap[] tempBitmap = new Bitmap[tempTotal];
finalTotal = tempTotal;
for (int pageNum = 0; pageNum < tempTotal; pageNum++) {
PdfRenderer.Page tempPage = pdfRenderer.openPage(pageNum);
tempBitmap[pageNum] = Bitmap.createBitmap(WS_WIDTH, WS_HEIGHT, Bitmap.Config.ARGB_8888);
tempPage.render(tempBitmap[pageNum], null, null, PdfRenderer.Page.RENDER_MODE_FOR_PRINT);
if (tempBitmap[pageNum].getPixel(0, 0) == Color.GRAY) {
finalTotal--;
}
tempPage.close();
}
}
It works fine. At least should cause no problem if the users only attempt to print PDF files constructed with my app. :P
Please tell me if you know a better way to do this. Thanks!
I am currently creating a map which updates based on users selection and displays 5 location closest to them. This works however when the user changes their selection the map updates and displays the 5 NEW locations as well as the 5 OLD locations.
I am not sure how to remove the old symbols.
public void displayResults(ArrayList allLocation) {
SymbolManager sm = new SymbolManager(mapView,map,styleMap);
sm.deleteAll();
SymList.clear();
sm.setIconAllowOverlap(true);
sm.setIconIgnorePlacement(true);
int count = 1;
for (LocationDetails a : allLocation
) {
// gets the distance from user to Location
double LocationLat = Double.parseDouble(a.getLatitude());
double LocationLng = Double.parseDouble(a.getLongitude());
float[] disResult = new float[1];
Location.distanceBetween(lat, lng, LocationLat, LocationLng, disResult);
results.append(count + ": " + a.getName() + " " + "\n");
distanceResults.append(Math.round(disResult[0]) + "m" + "\n");
SymbolOptions symbolOptions = new SymbolOptions()
.withLatLng(new LatLng(LocationLat, LocationLng))
.withIconImage("marker-11")
.withTextField(""+count)
.withIconColor("black")
.withIconSize(2.5f);
SymList.add(symbolOptions);
count++;
}
LatLngBounds latLngBounds = new LatLngBounds.Builder()
.include(SymList.get(0).getLatLng())
.include(SymList.get(1).getLatLng())
.include(SymList.get(2).getLatLng())
.include(SymList.get(3).getLatLng())
.include(SymList.get(4).getLatLng())
.build();
map.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 50), 2000);
for(SymbolOptions a : SymList){
sm.create(a);
}
SymList.clear();
}
I have been using mapbox for 3 months. After hours of research I discovered that on Android the only way to remove a Symbol or any element on the map was to reload all the elements from scratch. Unfortunately, there is currently no method to remove a single element.
So I suggest you create a container class in which to save your items.
If your use case only requires showing about five markers on the map at a time, it might be easier to use native sources and SymbolLayers rather than relying on the abstraction provided by the SymbolManager.
For example, this icon updates based on API response Android demo shows how to add a GeoJSON source and corresponding layer to the map, then update said source to get a different visual result. Basically all of the logic you will need is encapsulated here, but your GeoJSON will be a FeatureCollection of multiple (namely, 5) features rather than just one point.
So, you can set up your symbols similarly to how it's done in the linked example:
private void initSpaceStationSymbolLayer(#NonNull Style style) {
style.addImage("space-station-icon-id",
BitmapFactory.decodeResource(
this.getResources(), R.drawable.iss));
style.addSource(new GeoJsonSource("source-id"));
style.addLayer(new SymbolLayer("layer-id", "source-id").withProperties(
iconImage("space-station-icon-id"),
iconIgnorePlacement(true),
iconAllowOverlap(true),
iconSize(.7f)
));
}
, and then update the source's GeoJSON to the new locations closest to the user's position, similar to the updateMarkerPostion method:
private void updateMarkerPosition(LatLng position) {
// This method is where we update the marker position once we have new coordinates. First we
// check if this is the first time we are executing this handler, the best way to do this is
// check if marker is null;
if (map.getStyle() != null) {
GeoJsonSource spaceStationSource = map.getStyle().getSourceAs("source-id");
if (spaceStationSource != null) {
spaceStationSource.setGeoJson(FeatureCollection.fromFeature(
Feature.fromGeometry(Point.fromLngLat(position.getLongitude(), position.getLatitude()))));
}
}
// Lastly, animate the camera to the new position so the user
// wont have to search for the marker and then return.
map.animateCamera(CameraUpdateFactory.newLatLng(position));
}
A few modifications will need to be made, of course, but this option might be more direct for your implementation specifically.
First of all, check this out (link): it's an example program taken from the Processing Box2D library on github, which displays a box at the center of the screen (it can be moved around with the mouse) while a cascade of little balls fall on it; whenever a ball hits the box, that ball turns red. I copypasted the four .pde files into a single .pde sketch, run it, and it works perfectly.
Now, onto my problem. I'm currently making a game in Processing: you have a ball, a player 1 and a player 2 (both of which can be moved around using the keyboard). Box2D is in charge of the physical interactions between each player and the ball, and I must say it handles them pretty well. Each of the three main objects has its own class. Now, I want stuff to happen as soon as player 1 makes contact with the ball. And that example code seems perfect for this scope, right? It works on my computer, after all.
So, I started copying the relevant parts:
I copypasted all the 'import's at the beginning of my code;
I added box2d.listenForCollisions(); inside setup();
I also added these two functions at the very bottom of my sketch:
void beginContact(Contact cp) {
Fixture f1 = cp.getFixtureA();
Fixture f2 = cp.getFixtureB();
Body b1 = f1.getBody();
Body b2 = f2.getBody();
Object o1 = b1.getUserData();
Object o2 = b2.getUserData();
if (o1.getClass() == Box.class) {
Particle p = (Particle) o2;
p.change();
}
else if (o2.getClass() == Box.class) {
Particle p = (Particle) o1;
p.change();
}
}
void endContact(Contact cp) {
}
Which I promptly changed into this (I basically renamed the classes, and substituted p.change(), the method that turned the balls red in that sketch, with what I want to happen when contact is being made):
(... same ...)
if (o1.getClass() == Player.class) {
Ball p = (Ball) o2;
//do stuff when contact happens
}
else if (o2.getClass() == Player.class) {
Ball p = (Ball) o1;
//do stuff when contact happens
}
}
void endContact(Contact cp) {
}
But guess what? I get a 'Could not invoke the "beginContact()" method for some reason' error! I don't think I'm lacking any crucial files or libraries, since that example worked fine in my computer and all I did was just copypaste and run the code.
I cannot paste here my whole code because it's huge, but I swear the Player class (player 1 class), the Enemy class (player 2 class) and the Ball class all have their fixtures, and there's literally nothing in my classes that differs in a substantial way from those from the example sketch. The bodies are all of dynamic type, the players are rectangular boxes like the box in the example, and the ball is a pure circle like the little balls that turned red there.
What is happening? Did I miss an important line from that code? Even though the example code runs perfectly without needing any additional files, I should mention that the console also prints an 'at shiffman.box2d.Box2DContactListener.beginContact(Box2DContactListener.java:54)' error: now, like I said, I don't need that Box2DContactListener.java file in my computer to run the example sketch... but anyway, if I read it up online (link), I can see this is what it's referring to:
public void beginContact(Contact c) {
if (beginMethod != null) {
try {
beginMethod.invoke(parent, new Object[] { c });
} catch (Exception e) {
System.out.println("Could not invoke the \"beginContact()\" method for some reason.");
e.printStackTrace();
beginMethod = null;
}
}
}
Do you have any idea what's going on here?
Basically, before the if statement, you have to check if either of the objects is 'null'.
In case it is, you just have to break.
You can just simply paste this:
if (o1==null || o2==null)
return;
Looking for a GWT DataGrid component which implements infinite scroll, BUT also makes sure to discard the results no longer visible on the screen : such as the previously loaded results that are not shown anymore.
This is to avoid a memory hog.
I've been trying to find this on Google, but no luck so far.
Please note : I could take a JS library and adapt it to what I need, but I don't think it would work good with GWT's DataGrid component.
Edit: I am interested specifically in an infinite scroll which ALSO discards/releases the topmost results that are not visible (and loads them up as appropriate).
Any ideas ?
As a matter of fact the showcase example has an infinite scrolling CellList. (you can find the code there).
Although this was done with a CellList the same principles should also apply to a DataGrid.
Check out the ShowMorePagerPanel.java file.
Update:
The onScroll function of ShowMorePagerPanel.java will add the new records at the bottom. However you can easily change the behavior:
Something along the lines (not tested tough):
HasRows display = getDisplay();
if (display == null) {
return;
}
boolean loadData = false;
// If scrolling up, change newStart
int oldScrollPos = lastScrollPos;
lastScrollPos = scrollable.getVerticalScrollPosition();
// get the current visible Range
Range currentRange = display.getVisibleRange();
if (oldScrollPos >= lastScrollPos) {
int newStart = Math.max(
currentRange.getStart() - incrementSize,0);
loadData = true;
}
int maxScrollTop = scrollable.getWidget().getOffsetHeight()
- scrollable.getOffsetHeight();
if (lastScrollPos >= maxScrollTop) {
// We are near the end, so increase the page size.
int newPageSize = Math.min(
display.getVisibleRange().getLength() + incrementSize,
display.getRowCount());
loadData = true;
}
if (loadData) {
display.setVisibleRange(newStart, newPageSize);
}
I'm having a really weird problem while following the Gestures tutorial here: http://developer.android.com/resources/articles/gestures.html.
4 unique gestures are created in Gesture Builder: + - × /
Add and multiply are multi-stroke. Subtract and divide are single stroke.
The Activity loads the pre-built GestureLibrary (R.raw.gestures), adds an OnGesturePerformedListener to the GestureOverlayView, and ends with onGesturePerformed() when a gesture is detected & performed.
Activity layout in XML
<android.gesture.GestureOverlayView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gestures"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gestureStrokeType="multiple"
android:eventsInterceptionEnabled="true"
android:orientation="vertical"
/>
Located in onCreate()
mLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures);
if (!mLibrary.load()) {
finish();
}
GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures);
gestures.addOnGesturePerformedListener(this);
Located in onGesturePerformed()
ArrayList<Prediction> predictions = mLibrary.recognize(gesture);
// We want at least one prediction
if (predictions.size() > 0) {
Prediction prediction = predictions.get(0);
// We want at least some confidence in the result
if (prediction.score > 1.0) {
// Show the spell
Toast.makeText(this, prediction.name, Toast.LENGTH_SHORT).show();
}
}
The main problem is the pre-built gestures are not being recognized correctly. For example, onGesturePerformed() is never performed if a horizontal gesture is followed by a vertical (addition). The method is called if a vertical gesture is followed by a horizontal. This is how GesturesListDemo behaves too (GesturesDemos.zip # code.google.com).
Furthermore, the predicted gesture ends up being the incorrect gesture. Add is recognized as subtract; multiply as divide; Subtract as add. It's completely inconsistent.
Finally, add and subtract gestures typically share similar Prediction.score's, which is weird since they differ by an entire stroke.
Sorry about the long post -- wanted to be thorough. Any advice would be greatly appreciated, thanks all.
I realize this is a really old question, but it hasn't been answered yet and this might help someone. I just came across a similar problem and my solution was to use gesture.getStrokesCount() to differentiate between single- and multi-stroke gestures.
Example:
ArrayList<Prediction> predictions = mLibrary.recognize(gesture);
// We want at least one prediction
if (predictions.size() > 0) {
Prediction prediction = predictions.get(0);
// We want at least some confidence in the result
if (prediction.score > 1.0) {
if (gesture.getStrokesCount() > 1) {
// This is either add or multiply
}
else {
// This is either subtract or divide
}
}
}
Building on Drew Lederman his answer, you can use this implementation of onGesturePerformed to always get the best result:
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
ArrayList<Prediction> predictions = store.recognize(gesture);
double highScore = 0;
String gestureName = "";
for (Prediction prediction : predictions) {
if (prediction.score > SCORE && prediction.score > highScore &&
store.getGestures(prediction.name).get(0).getStrokesCount() == gesture.getStrokesCount()) {
highScore = prediction.score;
gestureName = prediction.name;
}
}
// Do something with gestureName
}
Yes, are supported, at least from Android 2.3.3. But it is heavily imprecise. Check the second example.