Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Add addImage, removeImage API #7610

Merged
merged 2 commits into from
Jan 9, 2017
Merged

Add addImage, removeImage API #7610

merged 2 commits into from
Jan 9, 2017

Conversation

bsudekum
Copy link

@bsudekum bsudekum commented Jan 5, 2017

This exposes the addImage and removeImage functions to platform: node. Example usage:

map.addImage('myImageName', {
  imageBuffer: <Premultiplied image buffer>,
  height: 40,
  width: 40
});

The developer then would add a corresponding layer, myImageName to style the image.

@jfirebaugh I'm not seeing tests for other similar APIs like addLayer. How should this be tested?

@bsudekum bsudekum added Node.js node-mapbox-gl-native ⚠️ DO NOT MERGE Work in progress, proof of concept, or on hold labels Jan 5, 2017
@bsudekum bsudekum requested a review from jfirebaugh January 5, 2017 23:10
@mention-bot
Copy link

@bsudekum, thanks for your PR! By analyzing this pull request, we identified @tmpsantos, @jfirebaugh and @tmcw to be potential reviewers.

@jfirebaugh
Copy link
Contributor

Can you make the following API adjustments:

  • Add a pixelRatio property to the options, and use it instead of hard-coding 1
  • Pass the image data as a standalone second argument, before options

So, you'd call it like:

map.addImage("id", data, {width: w, height: h, pixelRatio: r});

return Nan::ThrowTypeError("imageBuffer parameter required");
}

double imageHeight = Nan::Get(imageObject, Nan::New("height").ToLocalChecked()).ToLocalChecked()->NumberValue();
Copy link
Contributor

Choose a reason for hiding this comment

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

imageHeight and imageWidth should be integers -- validate the type using IsUint32 rather than IsNumber and convert using Uint32Value rather than NumberValue, assigning to a uint32_t rather than a double.

double imageHeight = Nan::Get(imageObject, Nan::New("height").ToLocalChecked()).ToLocalChecked()->NumberValue();
double imageWidth = Nan::Get(imageObject, Nan::New("width").ToLocalChecked()).ToLocalChecked()->NumberValue();
auto imageBuffer = Nan::Get(imageObject, Nan::New("imageBuffer").ToLocalChecked()).ToLocalChecked()->ToObject();

Copy link
Contributor

Choose a reason for hiding this comment

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

Add a check here that the expected size is correct:

if (node::Buffer::Length(imageBuffer) != imageHeight * imageWidth * 4) {
    return Nan::ThrowTypeError("image size does not match buffer size");
}

@tmpsantos
Copy link
Contributor

How should this be tested?

One option is to write an unit test like t.test('sets zoom before center', function(t) { ... } that uses pixelmatch for checking the rendering results.

platform/node/test/js/map.test.js:377

@jfirebaugh
Copy link
Contributor

It would be better to write a test-suite render test that can be used to test the implementation of the equivalent GL JS feature.

Similar tests of the runtime styling API are in this directory. Take a look at the "operations" key in the style.jsons in that tree to get an idea of how this works.

Since we can't embed literal image data into the style.json, the format I'd propose for the addImage operation is to pass the name of a file in the image directory, and leave it up to suite_implementation.js to load the image data at runtime.

@bsudekum
Copy link
Author

bsudekum commented Jan 6, 2017

@jfirebaugh started to go down the route of adding a custom addImage handler to suite_implementation.js. However, I'm not getting an added image to the map. Notice any issues?

@jfirebaugh
Copy link
Contributor

addImage doesn't work retroactively on layers that tried to use a previously non-existing image ID. Try waiting to add the symbol layer (using an addLayer operation) until after the image is added.

Also, let's require specifying an ID for the addImage operation, instead of reusing the path. (Using the intrinsic dimensions is fine though.)

@bsudekum
Copy link
Author

bsudekum commented Jan 6, 2017

@jfirebaugh this is ready for review

pixelRatio: 1
});

map.addLayer({
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be test-specific; that is the add-image test should use:

      "operations": [
        [
          "addImage",
          "marker",
          "./image/marker.png"
        ],
        [
          "addLayer",
          ...
        ],
        [
          "wait"
        ]
      ]


std::unique_ptr<uint8_t[]> data = std::make_unique<uint8_t[]>(node::Buffer::Length(imageBuffer));
std::copy(node::Buffer::Data(imageBuffer), node::Buffer::Data(imageBuffer) + node::Buffer::Length(imageBuffer), data.get());
mbgl::PremultipliedImage cPremultipliedImage({ static_cast<uint32_t>(imageWidth), static_cast<uint32_t>(imageHeight) }, std::move(data));
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't need static_casts here.

uint32_t imageHeight = Nan::Get(optionObject, Nan::New("height").ToLocalChecked()).ToLocalChecked()->Uint32Value();
uint32_t imageWidth = Nan::Get(optionObject, Nan::New("width").ToLocalChecked()).ToLocalChecked()->Uint32Value();

if (imageWidth > 1024 && imageHeight > 1024) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be || rather than &&.

});

applyOperations(operations.slice(1), callback);
} else if (operation[0] === 'addLayer') {
Copy link
Contributor

Choose a reason for hiding this comment

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

addLayer is already handled by the subsequent else block.

@jfirebaugh
Copy link
Contributor

Can you open a PR for the mapbox-gl-test-suite additions too?

@bsudekum
Copy link
Author

bsudekum commented Jan 6, 2017

uint32_t imageHeight = Nan::Get(optionObject, Nan::New("height").ToLocalChecked()).ToLocalChecked()->Uint32Value();
uint32_t imageWidth = Nan::Get(optionObject, Nan::New("width").ToLocalChecked()).ToLocalChecked()->Uint32Value();

if (imageWidth > 1024 || imageHeight > 1024) {
Copy link
Contributor

Choose a reason for hiding this comment

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

FYI, it’s possible for the image-adding operation to have no effect (and log to stderr) if the size of all the images combined exceeds this 1024-by-1024 square.

@bsudekum bsudekum removed the ⚠️ DO NOT MERGE Work in progress, proof of concept, or on hold label Jan 7, 2017
@bsudekum bsudekum merged commit 2988ca1 into master Jan 9, 2017
@bsudekum bsudekum deleted the bs-addImage branch January 9, 2017 21:03
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Node.js node-mapbox-gl-native
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants