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
WMS popup functionality #173
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we allow for the configuration to give a label to the returned field names?
event_name = Event name
pub_date = Publication date
And can we return the date in a more readable format, so the popup would read:
Event name: CHALANE-20
Publication date: 2020-12-30 07:34 UTC
Sure. Included in 7c4018a and redeployed to same url: http://homeless-giraffe.surge.sh |
Awesome. Great work Jorge. Looks good from my perspective. Over to @ericboucher for code review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Left some comments to help make the code more organized
@@ -48,7 +48,11 @@ const Input = forwardRef( | |||
); | |||
}, | |||
); | |||
function DateSelector({ availableDates = [], classes }: DateSelectorProps) { | |||
function DateSelector({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would use React.forwardRef, but in the future if we need a ref to the selector we'll run into issues. Up to you 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used a ref just to know current value from DateSelector. In both cases we would need to create the ref within the Mapview component and pass it to the DateSelector one.
Another option would be to use Localstorage, but some additional change will be needed within the addLayer reducer function
@@ -211,8 +278,43 @@ function MapView({ classes }: MapViewProps) { | |||
containerStyle={{ | |||
height: '100%', | |||
}} | |||
onClick={() => { | |||
onClick={(map: Map, evt: any) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any chance the library comes with a type for this? Would be nice to not use any. If it doesn't we could make an alias to any
called MapEvent
, or a bare bones type which has the fields we need.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to use the any
type, since many mapbox handlers use it as type across the project. It would be better to use any to keep consistency. If not, a change is needed for all mapbox event handlers with their respective type. But this should be addressed on another issue
const requestLayers = layers.filter(l => l.baseUrl === url); | ||
const layerNames = requestLayers.map(l => l.serverLayerName).join(','); | ||
|
||
const requestParams = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there's a type that lines up with this, we should use it:
const requestParams: <Type> ={...}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Included in 075838b. Needed to add a CamelCase to snake transformation function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use lodash's snakeCase
function https://lodash.com/docs/4.17.15#snakeCase
src/utils/server-utils.ts
Outdated
|
||
const wmsParams = { ...params, ...requestParams }; | ||
|
||
return fetch(formatUrl(`${url}/ows`, wmsParams)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make this more readable the async await
paradigm could be used, so all these intermediary steps can just be await <task>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Included in b1d8b95
@Ry-DS Feedback implemented on most of the comments. Please check |
@JorgeMartinezG They were hidden by GitHub because there were too many review comments haha. Let me know what you think of those 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting closer! Make sure to check out the comments I linked above, and to wrap up this PR I'd like if we spent some time to ensure our types are as strong as they can be.
src/components/MapView/index.tsx
Outdated
const params = getFeatureInfoParams(map, evt, dateFromRef); | ||
makeFeatureInfoRequest(featureInfoLayers, params).then( | ||
(result: any) => { | ||
if (result === null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
falsey check instead just in case the value is undefined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Included in 30953dd
url: string, | ||
wmsParams: requestFeatureInfo, | ||
layers: WMSLayerProps[], | ||
): Promise<{ [name: string]: string }> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On line 318 the API result is typed well, so we should be able to provide a good type as the output for this function. This can be done by typing the reduce
functions used in this file. What do you think? We should always try to make our types as strong as possible.
src/utils/server-utils.ts
Outdated
layers: WMSLayerProps[], | ||
): Promise<{ [name: string]: string }> { | ||
// Transform to snake case. | ||
const toSnakeWmsParams = Object.entries(wmsParams).reduce( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace with lodash's snakeCase function.
https://lodash.com/docs/4.17.15#snakeCase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
included in 73987d1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be clearer if called wmsParamsInSnakeCase
, what do you think?
layers: WMSLayerProps[], | ||
url: string, | ||
params: FeatureInfoType, | ||
): Promise<{ [name: string]: string }> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't define the return type here and just let TS infer it. The plan (imo) is to strongly type the return of runFeatureInfoRequest
and allow TS to infer the same type since you directly return the output of runFeatureInfoRequest
export async function makeFeatureInfoRequest( | ||
layers: WMSLayerProps[], | ||
params: FeatureInfoType, | ||
): Promise<{ [name: string]: string } | null> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless you're using an api without strong types, or an untyped library, we shouldn't make lose types like this. FOr MapEvent
, it is fair to use any
since the library doesn't give us a type, but from what I see we can make strong types using GeoJSON.FeatureCollection
. If you can't see an easy way to create types for this let me know :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Geojson standard has a strong type, but properties
field is a key, value container. It lets flexibility for including a wide range of possible keys and values. For PRISM and WFS, we extract the values from keys included within the layers.json file. I mean, we could add a type constraint for the response. However it would work only for a single layer, since ADAM have different property schemas accross its layers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not diving into the details here, but would like to add that flexibility on the types of data returned from the WFS feature request is important. We're solving for one dataset now (ADAM tropical storms), but more will come down the road, and we won't know how information is structured for each layer until we get into the integration steps. So being able to manage various types within the configuration of the layer is preferred.
const requests = urls.map(url => fetchFeatureInfo(layers, url, params)); | ||
|
||
return Promise.all(requests) | ||
.then(r => r.reduce((obj, item) => ({ ...obj, ...item }), {})) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these types will be stronger if we start using types for all the reduce
calls in this file:
arr.reduce<{output: string}>((arg1, arg2)=>{},{});
//or
arr.reduce((arg1, arg2)=>{},{} as {output: string});
…sm-frontend into feature/134-wms-feature-info
Looking great @JorgeMartinezG! Let us know when you had a chance to look at the remaining comments |
…sm-frontend into feature/134-wms-feature-info
I'm not sure, but most of the feedback has been addressed already. What was missing is some indicator in the popup that additional information is loading. I decided to add a LinearProgress and is addressed here: e8d0e89 Also, a change in a variable name in here: 1d5057e Please note that popup now is limited only within country boundaries, since two different events (map and layer) might be triggered at the same time, two popups might appear. This branch has been deployed to this endpoint: http://homeless-giraffe.surge.sh/ |
This PR closes #134
On a map click event, given the case that a selected layer has featureInfoProps array, prism executes a getFeatureInfo request to get information. The result is filtered given the labels in the array. For this PR, is used for mozambique wind buffers layer.
Deployment found here: http://homeless-giraffe.surge.sh/