def accept(self):
    """Creates and loads the WMS layer."""
    self.close()
    currentIndex = self.comboBoxLayer.currentIndex()
    currentLayerId, unused_dataType = self.comboBoxLayer.itemData(currentIndex)
    currentLayerName = unicode(self.comboBoxLayer.currentText())
    mapId = self.labelMapId.text()
    # Create the WMS layer
    token = oauth2_utils.getToken()
    url = 'https://mapsengine.google.com/%s-4/wms/%s/'
    wmsUrl = url % (mapId, token.access_token)
    currentFormatIndex = self.comboBoxFormat.currentIndex()
    imageFormat = unicode(self.comboBoxFormat.itemData(currentFormatIndex))
    crs = self.comboBoxCrs.currentText()

    uri = QgsDataSourceURI()
    uri.setParam('url', wmsUrl)
    uri.setParam('layers', currentLayerId)
    uri.setParam('format', imageFormat)
    uri.setParam('crs', crs)
    uri.setParam('styles', '')

    rlayer = QgsRasterLayer(str(uri.encodedUri()), currentLayerName, 'wms')
    if rlayer.isValid():
      QgsMapLayerRegistry.instance().addMapLayer(rlayer)
    else:
      logText = 'Failed to add WMS layer %s with URI %s' % (
          currentLayerName, str(uri.encodedUri()))
      warnText = 'Failed to add WMS layer %s' % currentLayerName
      QgsMessageLog.logMessage(logText, 'GMEConnector', QgsMessageLog.CRITICAL)
      self.iface.messageBar().pushMessage(
          'Google Maps Engine Connector', warnText,
          level=QgsMessageBar.CRITICAL, duration=3)
  def populateLayersOWS(self, gmeMap):
    """Adds layer information to comboBoxLayer widget using OWSLib.

    Args:
      gmeMap: gme_map.Map object.
    """
    self.labelMapName.setText(gmeMap.name)
    self.labelMapId.setText(gmeMap.id)
    self.comboBoxLayer.clear()
    mapId = gmeMap.id
    # Create the WMS layer
    token = oauth2_utils.getToken()
    url = 'https://mapsengine.google.com/%s-4/wms/%s/'
    wmsUrl = url % (mapId, token.access_token)
    wms = WebMapService(wmsUrl)
    for layer in list(wms.contents):
      if wms[layer].abstract == 'Raster layer':
        dataType = 'image'
      elif wms[layer].abstract == 'Vector layer':
        dataType = 'table'
      elif wms[layer].abstract == 'Base layer':
        dataType = 'baselayer'
      else:
        dataType = 'unknown'

      userData = (layer, dataType)
      if dataType != 'unknown':
        self.comboBoxLayer.addItem(wms[layer].title, userData)
 def loadMapsForProject(self, projectId):
   index = self.comboBox.findData(projectId)
   self.comboBox.setCurrentIndex(index)
   settings.write('gmeconnector/LAST_USED_PROJECT', projectId)
   api = gme_api.GoogleMapsEngineAPI(self.iface)
   token = oauth2_utils.getToken()
   self.maps = api.getMapsByProjectId(projectId, token)
   self.populateTable(self.maps)
   if len(self.maps) == 0:
     labelText = 'No maps found from account %s' % self.projectDict[projectId]
   else:
     labelText = 'Displaying %d maps from account %s' % (
         len(self.maps), self.projectDict[projectId])
   self.resultLabel.setText(labelText)
  def fetchFullLayer(self, layer):
    """Fetch full layer information.

    Args:
      layer: gme_item.Item object
    Returns:
      gme_layer.Layer object if successful, same object if failed.
    """
    api = gme_api.GoogleMapsEngineAPI(self.iface)
    token = oauth2_utils.getToken()
    gmeLayer = api.getLayerById(layer.id, token)
    if not gmeLayer:
      return layer
    else:
      return gmeLayer
  def accept(self):
    """Uploads the selected layer to maps engine."""
    self.close()
    self.iface.messageBar().pushMessage(
        'Google Maps Engine Connector', 'Uploading data. Please wait...',
        level=QgsMessageBar.INFO)
    QCoreApplication.processEvents()
    currentProject = self.comboBoxProjects.currentIndex()

    acl = unicode(self.lineEditAcl.text())
    tags = unicode(self.lineEditTags.text())

    # TODO: use with tempfile.TemporaryDirectory() instead of try/finally.
    tempDir = tempfile.mkdtemp()
    try:
      currentLayer = self.iface.mapCanvas().currentLayer()
      if currentLayer.type() == QgsMapLayer.VectorLayer:
        filesToUpload = self.extractVectorLayer(tempDir)
      elif currentLayer.type() == QgsMapLayer.RasterLayer:
        filesToUpload = self.extractRasterLayer(tempDir)
      else:
        QgsMessageLog.logMessage('Unsupported layer type.', 'GMEConnector',
                                 QgsMessageLog.CRITICAL)
        filesToUpload = []

      if not filesToUpload:
        self.iface.messageBar().clearWidgets()
        self.iface.messageBar().pushMessage(
            'Google Maps Engine Connector', 'Extraction failed.',
            level=QgsMessageBar.CRITICAL, duration=3)
        QgsMessageLog.logMessage('Extraction failed', 'GMEConnector',
                                 QgsMessageLog.CRITICAL)
        return

      data = {}
      data['projectId'] = unicode(
          self.comboBoxProjects.itemData(currentProject))
      data['name'] = unicode(self.lineEditDestinationName.text())
      data['description'] = unicode(self.lineEditDescription.text())
      data['files'] = [{'filename': x} for x in filesToUpload]
      if acl:
        data['draftAccessList'] = acl
      if tags:
        data['tags'] = [unicode(x) for x in tags.split(',')]

      if currentLayer.type() == QgsMapLayer.VectorLayer:
        data_type = 'tables'
      elif currentLayer.type() == QgsMapLayer.RasterLayer:
        # attribution to be specified for raster layers only.
        data['attribution'] = unicode(self.lineEditAttribution.text())
        data_type = 'rasters'
      else:
        QgsMessageLog.logMessage('Unsupported layer type.', 'GMEConnector',
                                 QgsMessageLog.CRITICAL)

      token = oauth2_utils.getToken()
      api = gme_api.GoogleMapsEngineAPI(self.iface)
      assetId = api.postCreateAsset(data_type, data, token)
      if not assetId:
        self.iface.messageBar().clearWidgets()
        self.iface.messageBar().pushMessage(
            'Google Maps Engine Connector', 'Upload failed.',
            level=QgsMessageBar.CRITICAL, duration=3)
        QgsMessageLog.logMessage('Upload failed', 'GMEConnector',
                                 QgsMessageLog.CRITICAL)
        return

      msg = 'Asset creation successful. Asset ID: %s' % assetId
      self.iface.messageBar().pushMessage(
          'Google Maps Engine Connector', msg, level=QgsMessageBar.INFO)
      QgsMessageLog.logMessage(msg, 'GMEConnector', QgsMessageLog.INFO)
      for fileName in filesToUpload:
        msg = 'Uploading file %s' % filesToUpload[fileName]
        self.iface.messageBar().pushMessage(
            'Google Maps Engine Connector', msg, level=QgsMessageBar.INFO)
        QCoreApplication.processEvents()

        content = open(filesToUpload[fileName], 'rb').read()
        api.postUploadFile(assetId, data_type, fileName, content, token)

      self.iface.messageBar().clearWidgets()

      # Open the newly created asset in web browser
      url = ('https://mapsengine.google.com/admin/'
             '#RepositoryPlace:cid=%s&'
             'v=DETAIL_INFO&aid=%s')
      # The assetId returned by the API in a globally unique id of the form
      # 'project_id-asset_id'. Split the assetId to get the project_id
      # parameter (cid) in the url.
      gmeUrl = url % (assetId.split('-')[0], assetId)
      webbrowser.open(gmeUrl)
    finally:
      # Cleanup
      shutil.rmtree(tempDir)
  def accept(self):
    """Fetches the selected map and loads it in map canvas.

    Creates a new vector layer with features representing the bounding boxes for
    the map as well as all layers contained in the map. The layer is added to
    the QGIS canvas with the map feature selected.
    """
    # Close the dialog immediately and start the process of creating the layer.
    self.close()

    # Get the map identifier
    selection = self.tableWidget.selectionModel()
    selectionList = selection.selectedRows()
    row = selectionList[0].row()
    selectedMapId = self.tableWidget.item(row, 0).text()
    selectedMapName = self.tableWidget.item(row, 1).text()

    dislayText = 'Fetching map: %s. Please wait...' % selectedMapName
    self.iface.messageBar().pushMessage(
        'Google Maps Engine Connector', dislayText, level=QgsMessageBar.INFO)
    QCoreApplication.processEvents()

    api = gme_api.GoogleMapsEngineAPI(self.iface)
    token = oauth2_utils.getToken()
    gmeMap = api.getMapById(selectedMapId, token)
    gmeLayers = self.getLayers(gmeMap)
    self.iface.messageBar().clearWidgets()
    self.iface.messageBar().pushMessage(
        'Google Maps Engine Connector',
        'View tools are now enabled.',
        level=QgsMessageBar.INFO, duration=6)

    dislayText = 'Loaded map: %s.' % gmeMap.name
    self.iface.messageBar().pushMessage(
        'Google Maps Engine Connector', dislayText,
        level=QgsMessageBar.INFO, duration=3)
    vectorLayer = self.createVectorLayer(gmeMap.name)
    provider = vectorLayer.dataProvider()
    vectorLayer.startEditing()
    # Add the map
    mapFeature = QgsFeature()
    projectId = gmeMap.id.split('-')[0]
    if gmeMap.bbox:
      geom = self.getGeomFromBbox(gmeMap.bbox)
      mapFeature.setGeometry(geom)
    else:
      errorMsg = 'Map %s does not have a geometry' % gmeMap.id
      QgsMessageLog.logMessage(errorMsg, 'GMEConnector', QgsMessageLog.WARNING)
      mapFeature.setGeometry(worldGeom)
    mapFeature.setAttributes([projectId, gmeMap.id, gmeMap.id,
                              projectId, 'map', gmeMap.name, 'n/a'])
    provider.addFeatures([mapFeature])

    # Add the layers
    for gmeLayer in gmeLayers:
      layerFeature = QgsFeature()
      projectId = gmeMap.id.split('-')[0]
      try:
        geom = self.getGeomFromBbox(gmeLayer.bbox)
        layerFeature.setGeometry(geom)
      except AttributeError:
        errorMsg = 'Layer %s does not have a geometry' % gmeLayer.id
        QgsMessageLog.logMessage(errorMsg, 'GMEConnector',
                                 QgsMessageLog.WARNING)
        layerFeature.setGeometry(worldGeom)

      try:
        datasourceType = gmeLayer.datasourceType
      except AttributeError:
        datasourceType = 'unknown'

      layerFeature.setAttributes([projectId, gmeMap.id, gmeLayer.id,
                                  gmeMap.id, 'layer', gmeLayer.name,
                                  datasourceType])
      provider.addFeatures([layerFeature])

    # Finalize the vector layer
    vectorLayer.updateExtents()
    vectorLayer.commitChanges()

    # Add the layer to the canvas
    vectorLayer.loadNamedStyle(
        ':/plugins/googlemapsengineconnector/styles/catalog_style.qml')
    QgsMapLayerRegistry.instance().addMapLayer(vectorLayer)

    # Zoom to the newly added layer
    self.iface.mapCanvas().setExtent(vectorLayer.extent())

    # Pre-select the map feature
    # This triggers the signal to enable other tools
    for feature in vectorLayer.getFeatures():
      if 'map' in feature.attributes():
        vectorLayer.setSelectedFeatures([feature.id()])
  def accept(self):
    """Uploads the selected layer to maps engine."""
    self.close()
    self.iface.messageBar().pushMessage(
        'Google Maps Engine Connector', 'Uploading data. Please wait...',
        level=QgsMessageBar.INFO)
    QCoreApplication.processEvents()
    currentProject = self.comboBoxProjects.currentIndex()
    projectId = unicode(
        self.comboBoxProjects.itemData(currentProject))

    currentLayer = self.lineEditLayerName.text()
    layerName = unicode(self.lineEditLayerName.text())

    acl = unicode(self.lineEditAcl.text())
    encoding = unicode(self.lineEditEncoding.text())
    tags = unicode(self.lineEditTags.text())

    # Extract the features from the current layer to a temporary shapefile.
    # This shapefile would be uploaded to maps engine. This approach ensures
    # that we are able to upload any layer that QGIS has ability to read,
    # including CSV files, databases etc.

    # TODO: use with tempfile.TemporaryDirectory() instead of try/finally.
    try:
      tempDir = tempfile.mkdtemp()
      tempShpPath = os.path.join(tempDir, layerName + '.shp')

      outputCrs = QgsCoordinateReferenceSystem(
          4326, QgsCoordinateReferenceSystem.EpsgCrsId)
      currentLayer = self.iface.mapCanvas().currentLayer()
      self.iface.messageBar().pushMessage(
          'Google Maps Engine Connector',
          'Extracting data to a temporary shapefile. Please wait...',
          level=QgsMessageBar.INFO)
      error = QgsVectorFileWriter.writeAsVectorFormat(
          currentLayer, tempShpPath, encoding.lower(),
          outputCrs, 'ESRI Shapefile')

      if error != QgsVectorFileWriter.NoError:
        self.iface.messageBar().clearWidgets()
        self.iface.messageBar().pushMessage(
            'Google Maps Engine Connector', 'Extraction to shapefile failed.',
            level=QgsMessageBar.CRITICAL, duration=3)
        QgsMessageLog.logMessage('Extraction to shapefile failed.',
                                 'GMEConnector', QgsMessageLog.CRITICAL)
        return None

      filesToUpload = {}
      for ext in ('shp', 'shx', 'dbf', 'prj'):
        fileName = '%s.%s' % (layerName, ext)
        filePath = os.path.join(tempDir, fileName)
        filesToUpload[fileName] = filePath

      data = {}
      data['name'] = unicode(self.lineEditDestinationName.text())
      data['description'] = unicode(self.lineEditDescription.text())
      data['files'] = [{'filename': x} for x in filesToUpload]
      data['sharedAccessList'] = acl
      if tags:
        data['tags'] = [unicode(x) for x in tags.split(',')]
      data['sourceEncoding'] = encoding

      token = oauth2_utils.getToken()
      api = gme_api.GoogleMapsEngineAPI(self.iface)
      assetId = api.postCreateAsset(projectId, data, token)
      if not assetId:
        self.iface.messageBar().clearWidgets()
        self.iface.messageBar().pushMessage(
            'Google Maps Engine Connector', 'Upload failed.',
            level=QgsMessageBar.CRITICAL, duration=3)
        QgsMessageLog.logMessage('Upload failed', 'GMEConnector',
                                 QgsMessageLog.CRITICAL)
        return

      msg = 'Asset creation successful. Asset ID: %s' % assetId
      self.iface.messageBar().pushMessage(
          'Google Maps Engine Connector', msg, level=QgsMessageBar.INFO)
      for fileName in filesToUpload:
        msg = 'Uploading file %s' % filesToUpload[fileName]
        self.iface.messageBar().pushMessage(
            'Google Maps Engine Connector', msg, level=QgsMessageBar.INFO)
        QCoreApplication.processEvents()

        content = open(filesToUpload[fileName]).read()
        api.postUploadFile(assetId, fileName, content, token)

      self.iface.messageBar().clearWidgets()

      # Open the newly created asset in web browser
      url = ('https://mapsengine.google.com/admin/'
             '#RepositoryPlace:cid=%s&'
             'v=DETAIL_INFO&aid=%s')
      gmeUrl = url % (assetId.split('-')[0], assetId)
      webbrowser.open(gmeUrl)
    finally:
      # Cleanup
      shutil.rmtree(tempDir)