Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/fit to coordinates #545

Merged

Conversation

naoufal
Copy link
Contributor

@naoufal naoufal commented Sep 6, 2016

Overview

  • Adds a fitToCoordinates method to <MapView />
  • Adds documentation for the method
  • Adds an example

Demo

fit-to-coordinates mov

Why?

I'm implementing a UI that requires the map to focus on a polyline or mix of polyline and markers. The current fitToSuppliedMarkers method comes short as it only supports markers. At first, I thought about adding and identifier prop to polylines, but I decided against it since one might want to focus on a specific part of a polyline. I settled on coordinates as I feel it's a more flexible API that covers a wider range of use cases.

Questions

I can see some people omitting edgePadding which would have function calls look like fitToCoordinates(coords, null, true). It's not the prettiest, so I was hoping to get feedback on adding a second method for developers that require edgePadding. Something like:

class MapView extends React.Component {
  // ...

  fitToCoordinates(coordinates, animated) {
    this.fitToCoordinates(coordinates, undefined, animated);
  }

  fitToCoordinatesWithEdgePadding(coordinates, edgePadding, animated) {
    this._runCommand('fitToCoordinates', [coordinates, edgePadding, animated]);
  }

  // ...
}

To do

@lelandrichardson
Copy link
Collaborator

@naoufal wow, this looks really good! Is there any way you'd be willing to tackle adding this API to android as well? We are trying our best to keep this component have feature parity cross-platform.

@naoufal
Copy link
Contributor Author

naoufal commented Sep 7, 2016

@lelandrichardson Yeah, I can give it a shot this weekend.

What are you thoughts on fitToCoordinates vs fitToCoordinatesWithEdgePadding?

@@ -399,6 +399,10 @@ class MapView extends React.Component {
this._runCommand('fitToSuppliedMarkers', [markers, animated]);
}

fitToCoordinates(coordinates, edgePadding, animated) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about providing default arguments? Something like:

fitToCoordinates(coordinates, edgePadding = {}, animated = true) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spikebrehm I initially had { top: 0, right: 0, bottom: 0, left: 0 } as a default argument, but then realized setVisibleMapRect could be called without edgePadding altogether. So I moved the conditional to the native side.

I don't mind switching to the default argument instead, whatever you guys prefer -- I'm easy.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could also add some documentation to this method that explains the possible keys of edgePadding. Either with a comment, or again using default arguments as documentation:

fitToCoordinates(coordinates, edgePadding = { top = 0, right = 0, bottom = 0, left = 0 }, animated = true) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spikebrehm I'll update it to use the default arguments.

As for additional documentation, I included an EdgePadding type to the MapView docs

@spikebrehm
Copy link

Looks really nice! I'm partial to just a single fitToCoordinates() with default arguments, but I could be convinced either way.

@naoufal
Copy link
Contributor Author

naoufal commented Sep 7, 2016

@spikebrehm I'm also for a single fitToCoordinates.

@lelandrichardson
Copy link
Collaborator

fitToCoordinates is fine, as long as we preserve the option for providing a padding amount

@chrisknepper
Copy link
Contributor

@naoufal Let me know if you'd like any assistance with the Android stuff!

This would be a great feature for sure. I implemented similar behavior for my project in JS but if we can make it a native feature of the plugin, all the better.

@naoufal
Copy link
Contributor Author

naoufal commented Sep 10, 2016

@chrisknepper That'd be great! I'm struggling to get my Android environment setup. You can get in touch with me on the Reactiflux chat if you have any questions.

@chrisknepper
Copy link
Contributor

@naoufal I think I have gotten this working on Android (except for edgePadding). I'll be contacting you shortly over at Reactiflux.

rn-maps-coords

@naoufal
Copy link
Contributor Author

naoufal commented Sep 12, 2016

@chrisknepper Looks great!

@@ -549,6 +549,33 @@ public void fitToSuppliedMarkers(ReadableArray markerIDsArray, boolean animated)
}
}

public void fitToCoordinates(ReadableArray coordinatesArray, ReadableMap edgePadding, boolean animated) {
//Log.d("AirMapView", "running thru the 6 with my woes");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, forgot to remove that last night 😪

@naoufal
Copy link
Contributor Author

naoufal commented Sep 13, 2016

@chrisknepper Is the Android part ready for review?

LatLngBounds bounds = builder.build();
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 50);

if(edgePadding != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting nit

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where at?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chrisknepper You're missing a space after your if on line 566.

@chrisknepper
Copy link
Contributor

chrisknepper commented Sep 13, 2016

@naoufal It is now ready for review. I'm not sure where the conflicts are but we should merge in the latest from here into your fork.

@naoufal naoufal force-pushed the feature/fit-to-coordinates branch from ab63b62 to 7742e6c Compare September 17, 2016 18:09
@naoufal
Copy link
Contributor Author

naoufal commented Sep 17, 2016

@spikebrehm, @lelandrichardson Alright, so I updated my changes based on the feedback provided, added an example to the main README and rebased off master to resolve the conflicts. @chrisknepper and I have both tested the example on our respective Android and iOS environments.

Can you run the examples on your machines and let me know if there's anything else I can do to help move this PR forward.

@chrisknepper
Copy link
Contributor

I have one suggestion for this. IMO, edgePadding should come after animated in the parameters. For the case when a user doesn't want to use edgePadding but wants animated to be true, they will have to explicitly pass null as the argument for edgePadding

This results in the call looking like this: fitToCoordinates(coords, null, true).
If animated was the 2nd parameter, it could be fitToCoordinates(coords, true).

This isn't a big deal and is just a semantics preference, but I envision this being frequently used without edgePadding. Just my two cents.

@naoufal
Copy link
Contributor Author

naoufal commented Sep 19, 2016

I'm in favour of keeping animated as the last argument for consistency. In my experience, edgePadding is used more frequently than animated for this use case. Not passing an edgePadding cuts the surrounding markers, so you typically need to add edgePadding to get the result you're looking for. You can see this first hand in the [example](https://github.com/airbnb/react-native-maps/pull/545/files#diff-218c7392a17180cda7a16429d00018aeR35). So I feel like passingnull` might be a rarer use case than you might think. I'd also prefer to have animated be the last argument in our methods, similarly to Cocoa methods.

I'd like to hear @spikebrehm and @lelandrichardson's thoughts on this.

@lelandrichardson
Copy link
Collaborator

Boolean parameters make me sad. I wonder if a better approach is fitToCoordinates(coordinates, options).

option could specify animated: false (animated: true would be default).
option could also have edgePadding: { ... } which would default to null, or 0, 0.

Just an idea. What do you all think?

@spikebrehm
Copy link

options is a good idea for optional parameters. That's my vote as well, but I don't feel strongly either way.

Also: note there's a merge conflict in example/App.js.

@naoufal
Copy link
Contributor Author

naoufal commented Sep 20, 2016

@lelandrichardson an options argument would solve this. My only concern is what it means for consistency since none of the other APIs accept options. We can probably go back and forth with this though, so I'll let you guys decide which interface you prefer and I'll gladly adjust the PR.

@spikebrehm Conflicts keep popping up as other PRs get merged in. I'm going to hold off fixing them until we've decided on the final API to avoid duplicating work.

@athaeryn
Copy link
Contributor

In #495 I was working on adding props to the map component to set pixel insets. The work there isn't complete, but I'm wondering if maybe having those inset props and a fitToCoordinates function that doesn't need to accept an edge padding argument might be a better design.

@spikebrehm
Copy link

We can probably go back and forth with this though, so I'll let you guys decide which interface you prefer and I'll gladly adjust the PR.

@naoufal sounds good! @lelandrichardson and I can migrate the other methods to take options before we cut the next breaking change.

@spikebrehm
Copy link

@athaeryn

In #495 I was working on adding props to the map component to set pixel insets. The work there isn't complete, but I'm wondering if maybe having those inset props and a fitToCoordinates function that doesn't need to accept an edge padding argument might be a better design.

Good point! If this gets merged before #495, we can cut a new release that utilizes pixel insets.

@naoufal let's go with the options arg, rebase this from master, and get this merged!

@naoufal
Copy link
Contributor Author

naoufal commented Sep 22, 2016

@spikebrehm Sounds good to me. I'll make the changes tonight and ping you 👍

@naoufal naoufal force-pushed the feature/fit-to-coordinates branch from df63ec5 to be02f25 Compare September 22, 2016 23:47
@naoufal naoufal force-pushed the feature/fit-to-coordinates branch from be02f25 to 1e81b06 Compare September 22, 2016 23:51
@naoufal
Copy link
Contributor Author

naoufal commented Sep 23, 2016

@spikebrehm Added the options argument and rebased. I'm good to go on my end.

@spikebrehm
Copy link

Beautiful, thank you! 🍻

@spikebrehm spikebrehm merged commit 7a5083c into react-native-maps:master Sep 23, 2016
@leandrobortolotto
Copy link

@naoufal I'm trying to use fitToCoordinates but without success. I'm on Mac OS and building to an iOS simulator. I can add markers but this method doesn't work. Here it's part of my code:

`const MARKER_COORDINATES = [ {latitude: -27.570351,longitude: -48.513944},
{latitude: -27.574329,longitude: -48.526673} ];

...

const DEFAULT_PADDING = { top: 40, right: 40, bottom: 40, left: 40 };

export default class TesteMapa extends Component {

fitAllMarkers() {
console.log()
console.log( this.map );
console.log( MARKER_COORDINATES.map );
this.map.fitToCoordinates(MARKER_COORDINATES, {
edgePadding: DEFAULT_PADDING,
animated: true,
});
console.log( "Method finished" );
}

`

I can see the log messages, etc. What am I missing?

Thanks

@avet-m
Copy link

avet-m commented Dec 17, 2018

Zoom level is too bug, when passing only one coordinate

_fitToCoordinates = (destSnapPoint) => {
        this.mapRef.current._component.fitToCoordinates(
            [{
                latitude: 59.978315,
                longitude: 30.314519,
                latitudeDelta: 0.02,
                longitudeDelta: 0.02,
            }],
            {
                edgePadding: {
                    top: 0,
                    right: 0,
                    bottom: destSnapPoint,
                    left: 0,
                },
                animated: true,
            },
        );
    };

#2629

@diegorodriguesvieira
Copy link

@naoufal Can you help me with fitToCoordinates, because it are ignoring mapPadding

#3308

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants